FPGARelated.com
Forums

about the always block in verilog

Started by yu zhou February 23, 2013
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??
On 2/23/2013 8:38 AM, yu zhou wrote:
> 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
On Saturday, February 23, 2013 5:38:40 AM UTC-8, yu zhou wrote:
> always @(negedge nrst or posedge PCLK or negedge begin) > ... > So,how can i determine what event does really happen in begin end block??
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 <=3D 0; if (!brst) foo <=3D 1;" etc. But to get the right behavio= r, you have to follow the (set/reset) priority of your library flop to get = the simulation behavior to match it. Lastly if you are just trying to get it to simulate it, you can write some = complicated case/if-else statements to check the state of every variable to= see which event has actually fired but you should realize that there is no= way this will be synthesis friendly.
muzaffer.kal@gmail.com wrote:
> On Saturday, February 23, 2013 5:38:40 AM UTC-8, yu zhou wrote: >> always @(negedge nrst or posedge PCLK or negedge begin) >> ... >> So,how can i determine what event does really happen in begin end block?? > > First of all begin is a reserved verilog keyword so "negedge begin" is going to give you heartache; change the identifier. > > Secondly if you want to synthesize this, you have to check if your target library supports two asynchronous inputs simultaneously. Some (asic) libraries have async set & reset flops so, it might synthesize if you write "if (!nrst) foo <= 0; if (!brst) foo <= 1;" etc. But to get the right behavior, you have to follow the (set/reset) priority of your library flop to get the simulation behavior to match it. > > Lastly if you are just trying to get it to simulate it, you can write some complicated case/if-else statements to check the state of every variable to see which event has actually fired but you should realize that there is no way this will be synthesis friendly.
The point I was making is that even with if/else logic, you can't always tell which event triggered the process, because there may be more than one signal which is in the state it would be if it had just triggered the process. You might be able to detect the event if you also kept track of the previous state of each variable, but the process won't do this for you, so you would need more registers for this. For simulation, it is more typical to use multiple processes to describe a flop with multiple asynchronous controls. Also note that to describe for example a D FF with async set and reset, you really need to be sensitive to both edges of the set and reset inputs to handle the case where both were asserted at the same time and then one of them released. I don't know of any synthesizers that allow you to infer this sort of flop, so I've always instantiated them if necessary. -- Gabor
yu zhou <zydgyy@gmail.com> wrote:
> 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??
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 <= 0; else q<=d; end (I might have that wrong, but maybe you see the idea.) If reset goes high, it resets. If reset is high on a clock positive edge, it stays reset. If reset is not high on a clock positive edge, it clocks data in. There are four cases here to consider. clk high or low on posedge reset, and reset high or low on posedge clk. (The tools usually don't know that there is the case that both change at once. In actual logic, it would usually be a setup/hold violation and/or race condition.) If you have three edge events, then you have to consider the state of the other two signals on any of the three events, for 12 combinations. Note the use of posedge reset, though the FF reset is not edge triggered. The only interesting thing happens on the posedge. The rest of the state has to depend on the current values of the other signals on the transition. (If reset is high, it stays reset even when a clk event occurs.) On the other hand: always @(posedge clk) begin if(reset) q <= 0; else q<=d; end generates a synchronous reset FF. -- glen
On 2/25/2013 9:05 AM, GaborSzakacs wrote:
> muzaffer.kal@gmail.com wrote: >> On Saturday, February 23, 2013 5:38:40 AM UTC-8, yu zhou wrote: >>> always @(negedge nrst or posedge PCLK or negedge begin) >>> ... >>> So,how can i determine what event does really happen in begin end >>> block?? >> >> First of all begin is a reserved verilog keyword so "negedge begin" is >> going to give you heartache; change the identifier. >> >> Secondly if you want to synthesize this, you have to check if your >> target library supports two asynchronous inputs simultaneously. Some >> (asic) libraries have async set & reset flops so, it might synthesize >> if you write "if (!nrst) foo <= 0; if (!brst) foo <= 1;" etc. But to >> get the right behavior, you have to follow the (set/reset) priority of >> your library flop to get the simulation behavior to match it. >> >> Lastly if you are just trying to get it to simulate it, you can write >> some complicated case/if-else statements to check the state of every >> variable to see which event has actually fired but you should realize >> that there is no way this will be synthesis friendly. > > The point I was making is that even with if/else logic, > you can't always tell which event triggered the process, > because there may be more than one signal which is in > the state it would be if it had just triggered the process. > > You might be able to detect the event if you also kept track > of the previous state of each variable, but the process > won't do this for you, so you would need more registers > for this.
This is different from VHDL. The signal keeps track of the current state, the prior state and whether or not the state changed for this delta cycle. rising_edge(foo) checks that foo is in the '1' state (or 'high' IIRC) and if the signal had just changed, foo'event=TRUE (or is it '1', again, I don't recall). These conditions can all be checked in the code using IF statements.
> For simulation, it is more typical to use multiple processes > to describe a flop with multiple asynchronous controls. Also > note that to describe for example a D FF with async set and reset, > you really need to be sensitive to both edges of the set and > reset inputs to handle the case where both were asserted at the > same time and then one of them released. I don't know of > any synthesizers that allow you to infer this sort of flop, > so I've always instantiated them if necessary.
I don't follow what you mean. I'm not as familiar with Verilog. In VHDL you would just include both the set and reset signal in the sensitivity list which runs the process anytime any of those signals change state. Then in the logic the states are checked to describe what the logic should do about it. Sometimes that will be nothing, for example on the falling edge of the rising edge sensitive clock signal. The process will be activated by the falling edge, but the code will not execute any assignments. A D FF with both set and reset async inputs is not hard to describe in VHDL. I can't imagine this is hard to describe in Verilog either. I don't understand what you mean by "I don't know of any synthesizers that allow you to infer this sort of flop". Is that really a limitation in Verilog? process(Clk, Reset, Set) begin if (Reset) then Q <= '0'; elsif (Set) then Q <= '1'; elsif (rising_edge(Clk)) then Q <= Dinput; end if; end process; In this case the Reset input has priority over the Set which has priority over the Clk. How do you do this in Verilog? I just realized that I need to download a Verilog cheat sheet. I have a couple for VHDL, but none for Verilog... my bad! Wouldn't you just write... always@(posedge Clk or Reset or Set) if (Reset)... -- Rick
On 2/25/2013 2:18 PM, glen herrmannsfeldt wrote:
> yu zhou<zydgyy@gmail.com> wrote: >> 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?? > > 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<= 0; > else q<=d; > end > > (I might have that wrong, but maybe you see the idea.) > > If reset goes high, it resets. > > If reset is high on a clock positive edge, it stays reset. > > If reset is not high on a clock positive edge, it clocks data in. > > There are four cases here to consider. clk high or low on > posedge reset, and reset high or low on posedge clk. > > (The tools usually don't know that there is the case that > both change at once. In actual logic, it would usually be > a setup/hold violation and/or race condition.) > > If you have three edge events, then you have to consider the > state of the other two signals on any of the three events, > for 12 combinations. > > Note the use of posedge reset, though the FF reset is not edge > triggered. The only interesting thing happens on the posedge. > The rest of the state has to depend on the current values of the > other signals on the transition. (If reset is high, it stays reset > even when a clk event occurs.)
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
rickman wrote:
> On 2/25/2013 9:05 AM, GaborSzakacs wrote: >> muzaffer.kal@gmail.com wrote: >>> On Saturday, February 23, 2013 5:38:40 AM UTC-8, yu zhou wrote: >>>> always @(negedge nrst or posedge PCLK or negedge begin) >>>> ... >>>> So,how can i determine what event does really happen in begin end >>>> block?? >>> >>> First of all begin is a reserved verilog keyword so "negedge begin" is >>> going to give you heartache; change the identifier. >>> >>> Secondly if you want to synthesize this, you have to check if your >>> target library supports two asynchronous inputs simultaneously. Some >>> (asic) libraries have async set & reset flops so, it might synthesize >>> if you write "if (!nrst) foo <= 0; if (!brst) foo <= 1;" etc. But to >>> get the right behavior, you have to follow the (set/reset) priority of >>> your library flop to get the simulation behavior to match it. >>> >>> Lastly if you are just trying to get it to simulate it, you can write >>> some complicated case/if-else statements to check the state of every >>> variable to see which event has actually fired but you should realize >>> that there is no way this will be synthesis friendly. >> >> The point I was making is that even with if/else logic, >> you can't always tell which event triggered the process, >> because there may be more than one signal which is in >> the state it would be if it had just triggered the process. >> >> You might be able to detect the event if you also kept track >> of the previous state of each variable, but the process >> won't do this for you, so you would need more registers >> for this. > > This is different from VHDL. The signal keeps track of the current > state, the prior state and whether or not the state changed for this > delta cycle. rising_edge(foo) checks that foo is in the '1' state (or > 'high' IIRC) and if the signal had just changed, foo'event=TRUE (or is > it '1', again, I don't recall). These conditions can all be checked in > the code using IF statements. > > >> For simulation, it is more typical to use multiple processes >> to describe a flop with multiple asynchronous controls. Also >> note that to describe for example a D FF with async set and reset, >> you really need to be sensitive to both edges of the set and >> reset inputs to handle the case where both were asserted at the >> same time and then one of them released. I don't know of >> any synthesizers that allow you to infer this sort of flop, >> so I've always instantiated them if necessary. > > I don't follow what you mean. I'm not as familiar with Verilog. In > VHDL you would just include both the set and reset signal in the > sensitivity list which runs the process anytime any of those signals > change state. Then in the logic the states are checked to describe what > the logic should do about it. Sometimes that will be nothing, for > example on the falling edge of the rising edge sensitive clock signal. > The process will be activated by the falling edge, but the code will not > execute any assignments. > > A D FF with both set and reset async inputs is not hard to describe in > VHDL. I can't imagine this is hard to describe in Verilog either. I > don't understand what you mean by "I don't know of any synthesizers that > allow you to infer this sort of flop". Is that really a limitation in > Verilog? > > process(Clk, Reset, Set) begin > if (Reset) then > Q <= '0'; > elsif (Set) then > Q <= '1'; > elsif (rising_edge(Clk)) then > Q <= Dinput; > end if; > end process; > > In this case the Reset input has priority over the Set which has > priority over the Clk. How do you do this in Verilog? I just realized > that I need to download a Verilog cheat sheet. I have a couple for > VHDL, but none for Verilog... my bad! > > Wouldn't you just write... > > always@(posedge Clk or Reset or Set) > if (Reset)... >
The problem in Verilog is that you can't place the edge dependancy in the if statements within the always block. A clocked block in Verilog has the edge dependencies in the sensitivity list itself and you use the if statement to check the current (post event) state of the signals. So you don't really have the equivalent of the VHDL code where the if statements for the set/reset are level triggered but the if statement for the clock is edge triggered. There was a prolonged discussion of this in comp.lang.verilog where the bottom line was that you need two processes to properly describe a D-FF with two asynchronous controls. Regarding your suggestion, the block would trigger on either edge of set or reset, and only on the rising edge of clk. Now if you wrote: always @ (posedge clk or reset or set) if (reset) Q <= 0; else if (set) Q <= 1; else Q <= D; Then the problem is that the final else cannot really check that you got here because of the rising clock edge. You could add: else if (clk) Q <= D; But even that would not work in the case where you released the last asynchronous input while the clock was already high. And since you don't get to this point until after the event that triggered the block, you can't say else @ (posedge clk) Q <= D; because that would say to wait for another rising edge. Bottom line, for Verilog to model this properly you need two processes: always @ (set or reset) if (reset) Q = 0; else if (set) Q = 1; always @ (posedge clk) Q <= D; Which works fine for simulation, but gives you a "multisource" error for synthesis. -- Gabor
rickman wrote:
> On 2/25/2013 2:18 PM, glen herrmannsfeldt wrote: >> yu zhou<zydgyy@gmail.com> wrote: >>> 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?? >> >> 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<= 0; >> else q<=d; >> end >> >> (I might have that wrong, but maybe you see the idea.) >> >> If reset goes high, it resets. >> >> If reset is high on a clock positive edge, it stays reset. >> >> If reset is not high on a clock positive edge, it clocks data in. >> >> There are four cases here to consider. clk high or low on >> posedge reset, and reset high or low on posedge clk. >> >> (The tools usually don't know that there is the case that >> both change at once. In actual logic, it would usually be >> a setup/hold violation and/or race condition.) >> >> If you have three edge events, then you have to consider the >> state of the other two signals on any of the three events, >> for 12 combinations. >> >> Note the use of posedge reset, though the FF reset is not edge >> triggered. The only interesting thing happens on the posedge. >> The rest of the state has to depend on the current values of the >> other signals on the transition. (If reset is high, it stays reset >> even when a clk event occurs.) > > 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? >
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
On 3/1/2013 4:35 PM, GaborSzakacs wrote:
> rickman wrote: >> On 2/25/2013 9:05 AM, GaborSzakacs wrote: >>> muzaffer.kal@gmail.com wrote: >>>> On Saturday, February 23, 2013 5:38:40 AM UTC-8, yu zhou wrote: >>>>> always @(negedge nrst or posedge PCLK or negedge begin) >>>>> ... >>>>> So,how can i determine what event does really happen in begin end >>>>> block?? >>>> >>>> First of all begin is a reserved verilog keyword so "negedge begin" is >>>> going to give you heartache; change the identifier. >>>> >>>> Secondly if you want to synthesize this, you have to check if your >>>> target library supports two asynchronous inputs simultaneously. Some >>>> (asic) libraries have async set & reset flops so, it might synthesize >>>> if you write "if (!nrst) foo <= 0; if (!brst) foo <= 1;" etc. But to >>>> get the right behavior, you have to follow the (set/reset) priority of >>>> your library flop to get the simulation behavior to match it. >>>> >>>> Lastly if you are just trying to get it to simulate it, you can write >>>> some complicated case/if-else statements to check the state of every >>>> variable to see which event has actually fired but you should realize >>>> that there is no way this will be synthesis friendly. >>> >>> The point I was making is that even with if/else logic, >>> you can't always tell which event triggered the process, >>> because there may be more than one signal which is in >>> the state it would be if it had just triggered the process. >>> >>> You might be able to detect the event if you also kept track >>> of the previous state of each variable, but the process >>> won't do this for you, so you would need more registers >>> for this. >> >> This is different from VHDL. The signal keeps track of the current >> state, the prior state and whether or not the state changed for this >> delta cycle. rising_edge(foo) checks that foo is in the '1' state (or >> 'high' IIRC) and if the signal had just changed, foo'event=TRUE (or is >> it '1', again, I don't recall). These conditions can all be checked in >> the code using IF statements. >> >> >>> For simulation, it is more typical to use multiple processes >>> to describe a flop with multiple asynchronous controls. Also >>> note that to describe for example a D FF with async set and reset, >>> you really need to be sensitive to both edges of the set and >>> reset inputs to handle the case where both were asserted at the >>> same time and then one of them released. I don't know of >>> any synthesizers that allow you to infer this sort of flop, >>> so I've always instantiated them if necessary. >> >> I don't follow what you mean. I'm not as familiar with Verilog. In >> VHDL you would just include both the set and reset signal in the >> sensitivity list which runs the process anytime any of those signals >> change state. Then in the logic the states are checked to describe >> what the logic should do about it. Sometimes that will be nothing, for >> example on the falling edge of the rising edge sensitive clock signal. >> The process will be activated by the falling edge, but the code will >> not execute any assignments. >> >> A D FF with both set and reset async inputs is not hard to describe in >> VHDL. I can't imagine this is hard to describe in Verilog either. I >> don't understand what you mean by "I don't know of any synthesizers >> that allow you to infer this sort of flop". Is that really a >> limitation in Verilog? >> >> process(Clk, Reset, Set) begin >> if (Reset) then >> Q <= '0'; >> elsif (Set) then >> Q <= '1'; >> elsif (rising_edge(Clk)) then >> Q <= Dinput; >> end if; >> end process; >> >> In this case the Reset input has priority over the Set which has >> priority over the Clk. How do you do this in Verilog? I just realized >> that I need to download a Verilog cheat sheet. I have a couple for >> VHDL, but none for Verilog... my bad! >> >> Wouldn't you just write... >> >> always@(posedge Clk or Reset or Set) >> if (Reset)... >> > The problem in Verilog is that you can't place the edge dependancy > in the if statements within the always block. A clocked block in > Verilog has the edge dependencies in the sensitivity list itself > and you use the if statement to check the current (post event) state > of the signals. So you don't really have the equivalent of the VHDL > code where the if statements for the set/reset are level triggered > but the if statement for the clock is edge triggered. There was a > prolonged discussion of this in comp.lang.verilog where the bottom > line was that you need two processes to properly describe a D-FF > with two asynchronous controls. > > Regarding your suggestion, the block would trigger on either > edge of set or reset, and only on the rising edge of clk. Now > if you wrote: > > always @ (posedge clk or reset or set) > if (reset) > Q <= 0; > else if (set) Q <= 1; > else Q <= D; > > Then the problem is that the final else cannot really check that you > got here because of the rising clock edge. You could add: > > else if (clk) Q <= D;
Yes, I get it. If the process was triggered by a falling edge of reset or set the code would do the same thing as a rising edge of clk.
> But even that would not work in the case where you released the > last asynchronous input while the clock was already high. And > since you don't get to this point until after the event that > triggered the block, you can't say else @ (posedge clk) Q <= D; > because that would say to wait for another rising edge. > > Bottom line, for Verilog to model this properly you need two processes: > > always @ (set or reset) > if (reset) Q = 0; > else if (set) Q = 1; > > always @ (posedge clk) > Q <= D; > > Which works fine for simulation, but gives you a "multisource" error > for synthesis.
Yes, indeed. Thanks for the info. -- Rick