Hi,
at FPGA gate level the reset is actually level-triggered, i.e. as long as reset is low, the register is held in reset. Depending on the FPGA you use, it might actually be an asynchronous active-high clear (as shown in the Cyclone IV handbook), or an asynchronous active-low clear (as shown in the Cyclone II handbook), but the synthesis tool will fix the logic for you. The only edge-sensitive element of a logic cell is the clock, which is always sensitive on the rising edge.
However, simulation works different. There is no syntax (as far as I know) that describes level-sensitivity. Therefore you define the sensitivity as "@(posedge clk or negedge reset)", which means the always-block will be "executed" whenever the clock goes high, or when the reset becomes asserted (becomes low). It does not matter what happens
while the reset is asserted, it only matters what happens when the reset
becomes asserted. Example:
- clock rising edge -> process becomes executed, the "else" path of your statement becomes executed since the reset is not asserted (i.e. not low)
- reset becomes low -> this is basically a reset falling edge -> process becomes executed, the "if" path of your statement becomes executed -> reset
- clock rising edge -> process becomes executed, the "if" path of your statement becomes executed, since the reset is still asserted (i.e. still low)
- reset becomes high -> nothing happens
- clock rising edge -> process becomes executed, the "else" path of your statement becomes executed since the reset is not asserted any more (i.e. not low again)
Keep in mind that the always@ is virtually irrelevant for synthesis; the synthesis tool only deduces from the overall structure (the "always" and the if-else) that it has to implement this piece of Verilog as a rising-edge clocked D-register, with an asynchronous active-low reset.
What I assume is that you did the if-else wrong. It has to look like this:
always @(posedge clk or negedge rst)
if(!rst)
q<=0;
else
q<=d;
If you do this instead, it won't work, as the second if will also execute:
always @(posedge clk or negedge rst)
if(!rst)
q<=0;
if(clk) // WRONG!
q<=d;
Best regards,
GooGooCluster