Inferring single-port ram

P

Per Magnus Řsthus

Guest
Hello all,

I'm using Altera Quartus II 9.1 with a DE2 board.

I want to infer a single-port RAM in my code, but I get a message
saying "Uninferred RAM logic due to asynchronous read". However, I
cannot find the asynchronous read in my design. One idea I have is
that the "address" is sometimes set in the same clock cycle as the
read - with a blocking statement - and that might be a problem.

And, by the way, my goal is not to implement this on the DE2 board,
but in an ASIC using Synopsys. The server running synopsys is very
slow though, so I thought I'd use Quartus just for a quick
synthesis :). I also have had this problem in earlier FPGA projects,
and had to work around it somehow, so I'd like to know what's wrong
with my coding style.

Anyhow, here's abstracts of my code. The thing I'd like to be a RAM is
the reg variable sbox. I've not included the code that does not relate
to sbox.

module wep_encrypt (
.....
reg [7:0] sbox [0:255];
......
always @ (posedge clk) begin
.....
case (state)
S_IDLE: begin
case (start_encrypt)
1: state <= S_SBOX_INIT;
default: state <= S_IDLE;
endcase
i = 0;
j = 0;
n <= 0;
port_A_addr <= plain_addr;
end
S_SBOX_INIT: begin
state <= (i == 255) ? S_SBOX_SWAP0 : S_SBOX_INIT;
sbox <= i;
i = i + 1; // Wraps around at 255.
j = 0;
end
S_SBOX_SWAP0: begin
temp <= sbox;
state <= S_SBOX_SWAP1;
end
S_SBOX_SWAP1: begin
j = j + temp + seed(i[2:0]);
temp2 <= sbox[j];
state <= S_SBOX_SWAP2;
end
S_SBOX_SWAP2: begin
sbox[j] <= temp; // sbox[j] <= sbox
state <= S_SBOX_SWAP3;
end
S_SBOX_SWAP3: begin
sbox <= temp2; // sbox <= sbox[j];
if (i == 255) begin
state <= S_ENCRYPT0;
i = 0;
j = 0;
end else begin
state <= S_SBOX_SWAP0;
i = i + 1'b1;
end
end
S_ENCRYPT0: begin
i = i + 1'b1;
temp <= sbox;
state <= S_ENCRYPT1;
end
S_ENCRYPT1: begin
j = j + temp;
temp2 <= sbox[j];
state <= S_ENCRYPT2;
end
S_ENCRYPT2: begin
sbox[j] <= temp; // sbox[j] <= sbox
index <= temp + temp2; // index <= sbox + sbox[j]
state <= S_ENCRYPT3;
end
S_ENCRYPT3: begin
sbox <= temp; // sbox <= sbox[j]
state <= S_ENCRYPT4;
end
S_ENCRYPT4: begin
case (n[1:0])
0: port_A_data_in[7:0] <= sbox[index] ^ port_A_data_out[7:0];
1: port_A_data_in[15:8] <= sbox[index] ^ port_A_data_out[15:8];
2: port_A_data_in[23:16] <= sbox[index] ^
port_A_data_out[23:16];
3: port_A_data_in[31:24] <= sbox[index] ^
port_A_data_out[31:24];
endcase
at_end = (n + 1 == frame_size);
if (n[1:0] == 3 || at_end) begin
// Either encrypted four bytes or done with the whole block.
// Store the result.
port_A_addr <= cipher_addr + (n & (~32'b11));
port_A_we <= 1'b1;
state <= at_end ? S_DONE : S_WRITE;
end else begin
state <= S_ENCRYPT0;
end
n <= n + 1;
end


Any help is greatly appreciated! :)
Best regards,
Per Magnus Řsthus
 
Oh, by the way, Quartus reports that the register implementing sbox
gets a "Clock enable" signal, and that does not infer a RAM, according
to the documentation. Does anyone see why a clock enable is created?
 
On Apr 28, 3:57 am, Per Magnus Řsthus <pmost...@gmail.com> wrote:
Oh, by the way, Quartus reports that the register implementing sbox
gets a "Clock enable" signal, and that does not infer a RAM, according
to the documentation. Does anyone see why a clock enable is created?
Either the address or the data needs to be registered - your synthesis
may work fine with either.

To get your memory to work, use the case statement to produce the
address and write enable and perform your read/write outside the case
statement.

The clock enable probably comes from the cycles where there isn't a
read, isn't a write, or neither occur. By getting your address, data,
and control to a very simple assignment outside the case, everything
flows.
 

Welcome to EDABoard.com

Sponsor

Back
Top