always @(negedge nrst or posedge PCLK or negedge begin) begin ... end
So,how can i determine what event does really happen in begin end block??
always @(negedge nrst or posedge PCLK or negedge begin) begin ... end
So,how can i determine what event does really happen in begin end block??
You can't. You can only test the current state of the variables in the sensitivity list. Luckily this isn't generally necessary for common synthesis constructs, and my guess is that anything with more than two edge events in the sensitivity list won't synthesize. For simulation, you would typically work around this by using multiple processes, since you don't have the same constraint of driving a signal from only one process like you would for synthesis.
-- Gabor
First of all begin is a reserved verilog keyword so "negedge begin" is goin g to give you heartache; change the identifier.
Secondly if you want to synthesize this, you have to check if your target l ibrary supports two asynchronous inputs simultaneously. Some (asic) librari es have async set & reset flops so, it might synthesize if you write "if (! nrst) foo
to give you heartache; change the identifier.
library supports two asynchronous inputs simultaneously. Some (asic) libraries have async set & reset flops so, it might synthesize if you write "if (!nrst) foo
If you can't figure it out, how would the synthesis tool or actual FF figure it out?
In a more usual case, you see something like:
always @(posedge clk or posedge reset) begin if(reset) q
Yes, that is the part I'm not clear on. What if the simulation starts with reset at '1'. Is an event generated on reset anyway so that the process runs and q is reset?
-- Rick
The problem always @ (posedge clk or reset or set) if (reset) Q
The simulation always starts with everything undriven. So initial statements at time zero, or initial values in a reg declaration will always create an edge. Thus I typically start my simulation with:
initial begin reset = 1; clk = 0; . . . #100 reset = 0; . . . end
And all of my asynchronous reset processes trigger at time zero. Note that a clock is typically initialized to zero which would trigger any negedge processes at time zero as well.
-- Gabor
Yes, indeed. Thanks for the info.
-- Rick
I have a fuzzy recollection that in VHDL they either changed or are discussing changing rising_edge so that it only triggers on a logic edge rather than triggering from a non-logic state like 'U' or 'X' or I assume even 'Z'. Maybe I'm only hallucinating, but I think I read this.
In any event, I'm pretty sure that initialization happens prior to the start of the simulation so that it can't cause edges, but I'm not certain. I think I would have a clear recollection if it could because I would have been doing that...
-- Rick
(snip)
But are there any useful cases where that is true?
Now, you can write plenty of things that don't make any sense in actual logic.
OK, now consider:
always @(posedge clk or posedge reset) begin if(reset) q For simulation, it is more typical to use multiple processes
In verilog, you might do something, but it might be the same thing that was done before.
I believe that would be more like a transparent latch. Note that it will also be executed on the falling edge of reset, and that reset will be 0 at that time.
always @(posedge clk or posedge reset) begin if(reset) q
(snip, someone wrote)
You could do that, but most real logic requires some clock cycles to get into the appropriate state. I know that many microprocessors require reset to be active for some number, maybe 50, clock cycles.
Now, for FPGAs the device usually does a global reset as it comes out of configuration, and you might want to simulate that.
Then again, it might be that FPGA simulation doesn't do initial.
-- glen
The problem I was concerned about with this was the case where the simulation starts with reset at a '1' and the edge is not generated. But I am told this does not happen. In Verilog initializations create edges. I am fairly sure that I have initialized signals in VHDL simulations and they do *not* result in an edge at the start of the simulation. I am not certain because there is normally the reset preventing a clock from being recognized.
To the best of my knowledge there are *no* double edge FFs. DDR inputs have separate FFs which capture the input on the opposite edges of the clock, or they double the clock with a PLL and clock the data twice in each clock cycle on the rising edge of the doubled clock.
-- Rick
Xilinx allows inference of "DualEdge" flip-flops for CoolRunner II series only. Their guide shows this template:
always @ (negedge clock or posedge clock) . . .
Or for VHDL
process (clock) begin if (clock'event) then . . .
It's not clear why Verilog uses both edges rather than just:
always @ (clock)
which would work for simulation, perhaps they need to tell the difference between a "clocked" vs combinatorial process, where the case of "always @ (clock)" would ignore the sensitivity list.
-- Gabor
DDR input primitives usually use separate SDR registers with separate outpu ts for the rising and falling edge clocked values, and sometimes the negati ve edge clocked value is realigned with the rising edge of the clock.
DDR output registers do exist and are inferrable by some tools (at least Sy nplify). Synplify recommends inferring two SDR registers and a mux controll ed by the clock level. Do not try this without ensuring that the synthesize r will convert it to a DDR register primitive.
The actual FPGA primitive implementation in the IOB is not clear; it could be two SDRs with an output mux selected by the clock level (and careful att ention to silicon path delays to avoid glitches), or it could be a Flanter circuit. Both of these implementations can be driven to emulate either an S DR or DDR output register.
Finally, the synthesis standard 1076.6-2004 identifies the methods of descr ibing a DDR register (two clocks or two edges of one clock). In the two-edg e model, both edges are tested explicitly, so the above code would not work .
Finally, if your device does not support DDR registers, you can emulate one yourself with a Flancter circuit.
Andy
for the rising and falling edge clocked values, and sometimes the negative edge clocked value is realigned with the rising edge of the clock.
Synplify). Synplify recommends inferring two SDR registers and a mux controlled by the clock level. Do not try this without ensuring that the synthesizer will convert it to a DDR register primitive.
two SDRs with an output mux selected by the clock level (and careful attention to silicon path delays to avoid glitches), or it could be a Flanter circuit. Both of these implementations can be driven to emulate either an SDR or DDR output register.
describing a DDR register (two clocks or two edges of one clock). In the two-edge model, both edges are tested explicitly, so the above code would not work.
yourself with a Flancter circuit.
The CoolRunner II series from Xilinx, which is the only family where I've seen support for dual edged flop inference, only use the dual edge as a clock doubler, not to build a true DDR flip-flop that has two D inputs. I've never seen a proper DDR flip-flop that you could infer from HDL.
-- Gabor
On Tuesday, March 5, 2013 11:39:11 AM UTC-6, Gabor wrote: snip... I've never seen a proper DDR flip-flop that you could infer from HDL. -- Gabor
What synthesis tool(s) have you used?
Synplify supports HDL inference of DDR output registers for Virtex II and later devices, and for Spartan 3 and later devices. These DDR registers have two D inputs.
Andy
later devices, and for Spartan 3 and later devices. These DDR registers have two D inputs.
I use XST because I can't afford a real synthesis tool. So what does the code look like to infer a DDR register with D0 and D1, C0 and C1 inputs? I would think (at least for Verilog) it would need two processes. Or can you only infer the register if the two clocks are the complements of the same signal?
-- Gabor
Gabor,
Per the reference manual, you use three processes: one for each (rise/fall) register, and one for a mux controlled by the clock level. You have to eith er use opposite edges of the same clock signal, or use two clocks from the same DCM that are 180 degrees apart in phase. As with most things in the re ference manual, they often support additional means (e.g. a single process with two clocks or both edges of one clock, mutually exclusive, as specifie d in 1076.6). I know they support dual-edged processes in which the same si gnal/variable is not assigned on both edges, so I suppose you could do it i n at most two, if not a single process (using variables for the registers a nd a mux assignment to the output signal after the last "end if":
process (rst, clk) is variable qr, qf: std_logic; begin if rst then qr := '0'; qf := '0'; elsif rising_edge(clk) then qr := d; elsif falling_edge(clk) then qf := d; end if; output
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.