Clear Filters
Clear Filters

How to get Simulink HDL Coder RAM with non power of 2 depth.

2 views (last 30 days)
Simulink RAMs ask the user for the address bits instead of the data depth, and then generate HDL using a power-of-2 depth. This may result in extra, unused RAMs to be inferred by a synthesis tool. For example if your RAM could be implemented in 3 chained Block RAMs of depth 2^10 for a total depth of 3*2^10 but due to the Simulink RAM specifying a depth of 2^12 (based on needing 12 address bits) the tool will use 4 Block RAMs instead of the minimum 3.
Is it possible to get Simulink to generate RAM HDL with a specified depth? The output code would look something like below:
module SimpleDualPortRAM_generic
(clk,
wr_din,
wr_addr,
wr_en,
rd_addr,
dout);
parameter integer DataWidth = 9;
parameter integer DataDepth = 12288;
localparam AddrWidth = $clog2(DataDepth);
input clk;
input [DataWidth - 1:0] wr_din; // parameterized width
input [AddrWidth - 1:0] wr_addr; // parameterized width
input wr_en; // ufix1
input [AddrWidth - 1:0] rd_addr; // parameterized width
output [DataWidth - 1:0] dout; // parameterized width
reg [DataWidth - 1:0] ram [DataDepth - 1:0];
reg [DataWidth - 1:0] data_int;
always @(posedge clk)
begin : SimpleDualPortRAM_generic_process
if (wr_en == 1'b1) begin
ram[wr_addr] <= wr_din;
end
data_int <= ram[rd_addr];
end
assign dout = data_int;
endmodule // SimpleDualPortRAM_generic

Accepted Answer

Kiran Kintali
Kiran Kintali on 29 May 2024
Edited: Kiran Kintali on 29 May 2024
Does this solve your usecase?
function y = ramBanksScalarInput(u, addr)
% addr --> 12bits
% u --> uint8
persistent ram1 ram2 ram3
if isempty(ram1)
ram1 = hdl.RAM;
ram2 = hdl.RAM;
ram3 = hdl.RAM;
end
% Input 'addr' is 12 bits (use the MSB two bits to figure out which RAM to populate)
% Each RAM instance itself is 2^10 size based on the ramAddr variable size
msb1 = bitget(addr, 12);
msb2 = bitget(addr, 11);
ramAddr = bitsliceget(addr,10,1);
if msb1 == 1 && msb2 == 1
y = ram1(u, ramAddr, true);
elseif msb1 == 1 && msb2 == 0
y = ram2(u, ramAddr, true);
elseif msb1 == 0 && msb2 == 1
y = ram3(u, ramAddr, true);
else
% error.
y = u;
end
  4 Comments
Michael Pratt
Michael Pratt on 29 May 2024
I think what I'm looking for would be to add a parameter to the Simulink RAM System blocks that lets you specify the depth and it would just pass that parameter on to the HDL in the line reg [DataWidth - 1:0] ram [DataDepth - 1:0]; instead of inferring it from the address width.
We tested this in Vivado (by manually editing the HDL) and it does synthesize in the way we want.
Kiran Kintali
Kiran Kintali on 29 May 2024
Sounds good. I will take the input to the HDL Coder development team.

Sign in to comment.

More Answers (1)

Kiran Kintali
Kiran Kintali on 28 May 2024
I wonder if you can use the RAM banks feature in HDL Coder.
If your data signal is a vector, HDL Coder infers an array of parallel RAM banks.
With vector data input, the address and write enable inputs can be both scalars or vectors. When you specify scalar inputs for the write enable and address ports, the system object applies the same operation to each RAM bank. Similarly, When your input data is a bus, the address and write enable inputs must be scalar, and HDL Coder infers an array of parallel RAM banks.
Consider RAM usage that could be matched by modelling a banked RAM with 3 RAM banks and an address size of 10.
Attaching a sample example of banked RAM feature supported by HDL Coder.
  1 Comment
Michael Pratt
Michael Pratt on 28 May 2024
I don't think this does what I'm looking for. I have a scalar data input and one address port with 3*2^10 addresses (actually the example code assumed 3*2^12 but it's similar). Simulink will always define a reg array sized up to the next power of 2, based on the address bitwidth. I would just like to be able to specify only the needed size for the HDL.
Maybe this is a problem because you either have to modfiy the simulation to not accept out of range address inputs, or allow for the possibility that the simulation would not match the HDL for these cases. Not sure which is preferred..

Sign in to comment.

Products


Release

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!