0
votes

As the title suggests, ISE is having trouble inferring block RAM from my code.

wire we;

reg hold = 0;
reg start = 0;

reg [12:0] addr = 0;
reg [23:0] command = 0;

reg [7:0] RAM [8191 : 0];

reg [7:0] rx_data_buffer = 0;

assign we = new_rx_data && !hold && start;

always@(posedge clk) begin

new_tx_data <= 1'b0;

if(!tx_busy && hold && !new_tx_data) begin

    new_tx_data <= 1'b1;        
    addr <= addr + 1'b1;

    tx_data_buffer <= RAM[addr];

    if(addr == 13'd8191)
        hold <= 0;

end

else if(new_rx_data && !hold) begin

    addr <= addr + 1'b1;
    command <= {command[15:0], rx_data};

    if(addr == 13'd8191)
        hold <= 1;

    if(start)
        led <= rx_data;

end

if(we)
    RAM[addr] <= rx_data;

if(command == 24'h242424) //$$$ in ASCII
    start <= 1;

end

I have deduced that the root of the problem is the write enable signal for my RAM. If I set it to VCC by writing

if(1'b1)
    RAM[addr] <= rx_data;

ISE infers RAM without an issue. However, this is not my intended behavior. I want the write enable signal to be

assign we = new_rx_data && !hold && start;

No matter what register I assign to "we" ISE tells me it'll be inferring distributed RAM. Has anyone dealt with this issue before?

1

1 Answers

0
votes

You have a couple things probably need to be addressed. I see you are using new_rx_data for your assign we. I don't see it assigned in your RTL. Is it floating? or an Input?

Addr is assigned within an IF and ELSEIF. There is no ELSE, so in my mind that means it doesn't get assigned under some conditions. Maybe it just retains value, but again it's not my preference to do that.

Another is that you are assigning using non-blocking assignments and potentially assigning the same variable twice(See new_tx_data), and I can't be certain how that will synthesize. If it is unsynthesizeable, I would hope the build would crash, but it does build, you might get unexpected results.

Having said that, you need to fix these things to make sure your simulation results match the real results. You a simulator who says odd ball assignments are okay and physical synthesis tool that resolves the issue a different way, the two results will probably be different.

So, the second thing you need to do is check your warnings. The synthesis tool will complain about things, and it may include a noxious warning about some of the signals you are working with. If one of the signals you are working with (check for those three signals in your assign we statement)is said to always be stuck high or always stuck low, you may have a state that means you can't write, or you can't read, or both. This will cause RAM to not be inferred. No point in making memory that isn't write able right? Your always going to read zeros, so I'll just hard wire the data bus to zero for you and be done with it.