Altera_Forum
Honored Contributor
10 years agoStratix V MLAB Byte Enable Issue
Hi,
I am trying to implement a very small memory as a data buffer attached to an Avalon-MM interface. As the memory is only 16bytes, and I require that the output be unregistered, I am using MLABs to implement this ram using the following altdpram instantiation:
altdpram# (
.byte_size (8),
.indata_aclr ("OFF"),
.indata_reg ("INCLOCK"),
.intended_device_family ("Stratix V"),
.lpm_type ("altdpram"),
.outdata_aclr ("OFF"),
.outdata_reg ("UNREGISTERED"),
.ram_block_type ("MLAB"),
.rdaddress_aclr ("OFF"),
.rdaddress_reg ("UNREGISTERED"),
.rdcontrol_aclr ("OFF"),
.rdcontrol_reg ("UNREGISTERED"),
.read_during_write_mode_mixed_ports("DONT_CARE"),
.width (32),
.widthad (2),
.width_byteena (4),
.wraddress_aclr ("OFF"),
.wraddress_reg ("INCLOCK"),
.wrcontrol_aclr ("OFF"),
.wrcontrol_reg ("INCLOCK")
) transferMemRead (
//Write port (from I2C)
.inclock (clock),
.inclocken (busy),
.wraddress (src_address),
.byteena (src_byteen),
.wren (src_write),
.data ({(4){src_data}}), //copy src data to all byte locations
//Read port (to AvMM)
.rdaddress (csr_address),
.q (csr_data),
.aclr (1'b0)
);
Basically when the busy flag is high, the MLAB contents will be written with data from an I2C read transfer. This transfer is done byte-wise whereas Nios works with 32bit words. As such I am using byte enables to select which byte is written - the byte enable is generated by a one-hot counter which I can see from signaltap is correctly producing the required sequence (4'd1,4'd2,4'd4,4'd8,4'd1,...). The byte enable is doing its job in that the incoming data byte is not written to all bytes, however, the contents of the non-enabled bytes is being cleared. To explain, I end up with the following sequence:
Byte En | Data In | Mem Contents
0001 | 0x45 | 0xFFFFFF45
0010 | 0x22 | 0xFFFF22FF <- Should be 0xFFFF2245
0100 | 0x55 | 0xFF55FFFF <- Should be 0xFF552245
1000 | 0xAA | 0xAAFFFFFF <- Should be 0xAA552245
Notice how the contents of the memory gets wiped - non-enabled bytes are getting replaced by 0xFF. I have a second memory going the other direction (from Nios to the I2C controller) which if I do byte-wise writes from Nios (using IOWR_8DIRECT), the same thing happens. If however from Nios I do a 32bit write (IOWR_32DIRECT), then the word is written correctly. So is there a reason for this? Is there something that I am missing about the byte enables that are causing this weird behavior?