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
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