Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17040 Discussions

How to prevent conversion to "equivalent circuits with latches"

Altera_Forum
Honored Contributor II
1,579 Views

Hi everyone... I'm currently working on a Rijndael (AES) Decryptor using the Stratix III family and trying to add a Key check when the Load signal is set to prevent RoundKey re-generation if the Key hasn't changed. However, every attempt I've been making has been incurring conversion to "equivalent circuits with latches" on Quartus II. 

 

Below is the related Code... Removing the if(RoundKey[0] == Key) sections compiles just fine but there will no longer be a Key Check. Is there any way to fix this without adding a LoadKey input? 

 

Your help is greatly appreciated. 

 

 

 

// Check Status of Key Generation,  

assign Done_Keys = |RoundKey[10][0:15]; 

 

 

// Store RoundKeys 

always @ (posedge clk or posedge Load) 

begin 

if( Load ) 

begin 

if( RoundKey[0] == Key ) 

// Better way to implement this part? 

RoundKey[10] <= RoundKey[10]; 

else 

RoundKey[10] <= {128{1'b0}}; 

end 

else if( !Done_Keys ) 

RoundKey[Round] <= RoundKey_New; 

end 

 

 

// Updates Round Counter 

always @ (posedge clk or posedge Load or posedge Reset or posedge Done_Keys) 

begin 

if( Reset ) 

Round <= 4'hx; 

else if( Load ) 

// Initialize Round Counter 

begin 

if( RoundKey[0] == Key ) 

Round <= 4'hb; 

else 

Round <= 4'h0; 

end 

else 

// Update Round 

Round <= (Done_Keys) ? Round - 4'h1 : Round + 4'h1; 

end 

 

 

 

 

 

FYI: For those that do not know AES, a key is taken and 10 additional RoundKeys are generated. ie RoundKey[0] = Key and RoundKey[1 thru 10] are the generated ones. To Encrypt, you use the RoundKeys in order (0 to 10). To Decrypt, you use them in reverse order. 

Since it takes one cycle to generate each key and 10 cycles for decryption, the Key Check can potentially cut the time in half.
0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
643 Views

The problem is caused by your overall design structure. The expression 

 

--- Quote Start ---  

always @ (posedge clk or posedge Load) 

begin 

if( Load ) 

--- Quote End ---  

 

would require flip-flops with asynchronous load input for an exact implementation. It's one thing, that Verilog syntax allows multiple clock sensitive conditions in an always block, but another, if these constructs are synthesizable. They are fine in simulation, of course. 

 

Hopefully, it can be changed to a true synchronous design with a clock and multiple enable signals (and possibly an asynchronous reset). As is, it's not synthesizable with most newer Altera FPGA, I think. 

 

P.S.: It should be considered, that asynchronous conditions, that override the synchronous action, apart from having no adequate hardware in many FPGA, are susceptible for timing problems and can effectively a prevent a reliable timing analysis.
0 Kudos
Altera_Forum
Honored Contributor II
643 Views

I wanted to add an asynchronous Load "feature" hence the second input. 

 

Without the Key Check functionality (basically remove the if( RoundKey[0] sections), everything compiles on on Quartus II for the Stratix III but I guess synthesis and proper functionality are two different things. 

 

 

I just learned Verilog as a final project for University and I'm not really a hardware guy to start with (background mostly in software and power) so pardon my limited knowledge. It is due in a week so I'll probably fiddle with it for another 2-3 days then concentrate on the report.
0 Kudos
Altera_Forum
Honored Contributor II
643 Views

Yes, I see. But you should try to find a way to use a synchronous load instead. Otherwise I can hardly imagine, how you want to achieve predictable design behaviour, apart from the present synthesis problems.

0 Kudos
Altera_Forum
Honored Contributor II
643 Views

The original design was actually Synchronous Load but I decided to convert it to async load and output to decrease processing by an average of 10% for Encryption and 5% for Decryption. 

 

When I think about it more... I may have misunderstood the idea of asynchronism. If the loading occurs close to a rising edge, initialization won't have enough time to process and throw everything off... 

If there's enough time, I'll try to convert it back to Synchronous.
0 Kudos
Reply