Description
Summary
I have a block ram memory I am trying to write. It is meant to be a drop in replacement for the standard block rams that vivado generates, but parameterisable and syntheisable (in addition to simulatable)
I have written it already in straight verilog and vhdl, my goal now is for the myhdl equivalent.
These memories are a little weird as they have a byte level mask. So for data getting written in, din
, there is another signal, wea
, which is len(din)/8
.
In verilog land it looks like this (this is what I am trying to get to):
always @(posedge clka) begin
integer i;
if (ena) begin
for (i=0; i<G_WEWIDTH; i=i+1) begin
if (wea[i]) begin
f_ram[addra][(8 * i)+:8] <= dina[(8 * i)+:8];
end
end
end
end
However when I try and write some thing that work in python/myhdl:
@always(clka.posedge)
def write():
if ena:
for i in range(len(wea)):
if wea[i]:
f_doutb[addra].next[(8*i)-1:8*i] = dina[(8*i)-1:8*i]
The code this generates:
always @(posedge clka) begin: BLOCKMEM2P_WRITE
integer i;
if (ena) begin
for (i=0; i<4; i=i+1) begin
if (wea[i]) begin
f_doutb[addra][((8 * i) - 1)-1:(8 * i)] <= dina[((8 * i) - 1)-1:(8 * i)];
end
end
end
end
Will not go through icarus:
../myhdl/blockmem2p.v:50: error: A reference to a wire or reg (`i') is not allowed in a constant expression.
../myhdl/blockmem2p.v:50: error: Part select expressions must be constant.
../myhdl/blockmem2p.v:50: : This lsb expression violates the rule: ('sd8)*(i)
Checking verilog spec, it will not accept a variable as the second argument of an array.
Python arrays doesn't allow you to specify a start index and an number of values to take, only [start, stop, step]
. Is it even possible to achieve code like this?
I have set up a working/failing example here, here is a failing github action (using cocotb) compared against the working verilog only version. Checkout the action
System information
MyHDL Version:
Current main branch on github
Python Version:
3.7-3.11