![]() |
|
|
|||||||
![]() |
VHDL - Async clear plus edge triggered Set/Clr ? |
|
|
Thread Tools | Search this Thread |
|
|
#1 |
|
How can I implement this behaviour in a synthesizable form?
IF async_clr = '1' OR RISING_EDGE(clr) THEN bit <= '0'; ELSIF RISING_EDGE(set) THEN bit <= '1' END IF; I am trying to model this behaviour but as far as my knowledge goes, multiple edge triggered signals are not synthesizable. Probably a state machine would do but I'm wondering if there's anything simpler. Any input on that? mhs000@gmail.com |
|
|
|
|
#2 |
|
Posts: n/a
|
On 28 Mar 2007 16:01:34 -0700, wrote:
>How can I implement this behaviour in a synthesizable form? > > IF async_clr = '1' OR RISING_EDGE(clr) THEN > bit <= '0'; > ELSIF RISING_EDGE(set) THEN > bit <= '1' > END IF; Standard answer, that works in all reasonable tools and technologies: use a Flancter... three processes, I'm afraid. NOTE VERY CAREFULLY that the result signal is asynchronous to any of your clocks, because it's set in one clock domain and unset in another. So it may need to be resynchronised before it can be used. --- clr_ff and set_ff are the edge detecting flip-flops. --- set_clr_bit is your desired flag. signal clr_ff, set_ff, set_clr_bit: std_logic; clr_ff_p: process (clr, async_clr) begin if async_clr = '1' then clr_ff <= '0'; elsif rising_edge(clr) then clr_ff <= set_ff; end if; end process; set_ff_p: process (set, async_clr) begin if async_clr = '1' then set_ff <= '0'; elsif rising_edge(set) then set_ff <= not clr_ff; end if; end process; flancter: set_clr_bit <= clr_ff xor set_ff; Thanks again to Bob Weinstein... -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated. Jonathan Bromley |
|
|
|
#3 |
|
Posts: n/a
|
John's reply is correct.
It is a simplification to the general form for creating a dual clock flop (i.e. DDR) out of SDR flops and xor gates. Some synthesizers (synplicity and quartus) will accept it all in one process, as below. The last time I checked, Precision took it, but did not get the registered reference to q1 correct (without warning). Try it and check it out before you use it. The more people that use this and demand their synthesis vendor implement it, the sooner it will be universally accepted. Like any dual edge flop, you must ensure that there is sufficient time between edges of the two clocks. This will not work with completely asynchronous clocks (neither will the flancter, though correct uses of it will ensure through handshaking that the two clocks have sufficient time between them). ddr: process (async_clr, clk1, clk2) is variable q1, q2 : std_logic; begin if async_clr = '1' then q1 := '0'; q2 := '0'; elsif rising_edge(clk1) then q1 := d1 xor q2; -- reg'd reference to q2 elsif rising_edge(clk2) then q2 := d2 xor q1; -- reg'd reference to q1 end if; q <= q1 xor q2; -- combo xor of reg'd q1 & q2 end process ddr; Andy On Mar 29, 6:07 am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com> wrote: > On 28 Mar 2007 16:01:34 -0700, mhs...@gmail.com wrote: > > >How can I implement this behaviour in a synthesizable form? > > > IF async_clr = '1' OR RISING_EDGE(clr) THEN > > bit <= '0'; > > ELSIF RISING_EDGE(set) THEN > > bit <= '1' > > END IF; > > Standard answer, that works in all reasonable tools and > technologies: use a Flancter... three processes, I'm afraid. > NOTE VERY CAREFULLY that the result signal is asynchronous > to any of your clocks, because it's set in one clock domain and > unset in another. So it may need to be resynchronised > before it can be used. > > --- clr_ff and set_ff are the edge detecting flip-flops. > --- set_clr_bit is your desired flag. > signal clr_ff, set_ff, set_clr_bit: std_logic; > > clr_ff_p: process (clr, async_clr) > begin > if async_clr = '1' then > clr_ff <= '0'; > elsif rising_edge(clr) then > clr_ff <= set_ff; > end if; > end process; > > set_ff_p: process (set, async_clr) > begin > if async_clr = '1' then > set_ff <= '0'; > elsif rising_edge(set) then > set_ff <= not clr_ff; > end if; > end process; > > flancter: set_clr_bit <= clr_ff xor set_ff; > > Thanks again to Bob Weinstein... > -- > Jonathan Bromley, Consultant > > DOULOS - Developing Design Know-how > VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services > > Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK > jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com > > The contents of this message may contain personal views which > are not the views of Doulos Ltd., unless specifically stated. Andy |
|
|
|
#4 |
|
Posts: n/a
|
On Mar 28, 6:01 pm, mhs...@gmail.com wrote:
> How can I implement this behaviour in a synthesizable form? > > IF async_clr = '1' OR RISING_EDGE(clr) THEN > bit <= '0'; > ELSIF RISING_EDGE(set) THEN > bit <= '1' > END IF; > > I am trying to model this behaviour but as far as my knowledge goes, > multiple edge triggered signals are not synthesizable. Probably a > state machine would do but I'm wondering if there's anything simpler. > Any input on that? Just wondering...does the FF need to be cleared on a signal edge? If not what about this: IF async_clr = '1' THEN bit <= '0'; ELSIF rising_edge( clk ) THEN IF sync_clr = '1' THEN bit <= '0'; ELSE bit <= data; END IF; END IF; -Dave Pollum Dave Pollum |
|
|
|
#5 |
|
Posts: n/a
|
On Mar 29, 7:05 am, "Dave Pollum" <vze24...@verizon.net> wrote: > Just wondering...does the FF need to be cleared on a signal edge? If > not what about this: > > IF async_clr = '1' THEN > bit <= '0'; > ELSIF rising_edge( clk ) THEN > IF sync_clr = '1' THEN > bit <= '0'; > ELSE > bit <= data; > END IF; > END IF; > > -Dave Pollum The only thing with that approach is that it will clear the bit any time sync_clr is '1' which makes it more like level sensitive. The reason I wanted it to be edge triggered is to implement some form of a handshake mechanism for a transaction. When you get an edge on a request line (the clr bit), it will automatically clear the "done" bit, but once the transaction has been done (with the set bit going high), I want done to be set to '1' even though the request line may be still high. M. Hamed |
|