DIGITAL SYSTM DSIGN VHDL Coding for FPGAs Unit 7 INTRODUCTION TO DIGITAL SYSTM DSIGN: Digital System Components Use of generic map to map parameters. xample: Digital Stopwatch xample: Lights Pattern mbedding s and registers in ASM diagrams.
DIGITAL SYSTM DSIGN Digital System Components: Finite State Machine, Datapath circuit Design Steps: Circuit Design, VHDL coding, Synthesis, Simulation, Place and Route (also pin assignment), and FPGA Programming and Testing. DATAPATH CIRCUIT Inputs FINIT STAT MACHIN CONTROL CIRCUIT Outputs
XAMPL: STOPWATCH The Stopwatch that counts in increments of /th of a second. Circuit design and VHDL implementation. Inputs: Pause,, Outputs: Count on four 7-segment displays Target Board: DIGILNT NXYS-4 Board pause DIGITAL CIRCUIT seconds hundredths of a second
XAMPL: STOPWATCH Datapath design: We need four s. Tree s modulo- and one module-6. Counter modulo-6 4 4 4 4-5 -9-9 -9 The figure depicts a generic modulo-n, where n = log 2 N TIMING DIAGRAM - COUNTR MODULO (N=, n = 4) Q COUNTR modulo-n to N- n Q 2 3 4 5 6 7 8 9
DIGITAL COUNTR DSIGN Counters are usually designed as State Machines. However, for different counts, we need a different state machine. Moreover, if the count is large, the FSM gets intractable. More efficient manner: Think of them as accumulators. This way, the VHDL code is easier to read and modify (if we require a different count). xample: library ieee; use ieee.std_logic_64.all; use ieee.std_logic_unsigned.all; entity my_bcdcount is port (,, : in std_logic; Q: out std_logic_vector(3 downto ); : out std_logic); end my_bcdcount; architecture bhv of my_bcdcount is signal Qt: std_logic_vector(3 downto ); begin process (,,) begin if = '' then Qt <= ""; elsif ('event and ='') then if = '' then if Qt = ""' then Qt <= ""; else Qt <= Qt + ""; end if; end if; end if; end process; <= '' when Qt = "" else ''; Q <= Qt; end bhv;
COUNTR DSIGN: PARAMTRIC COD The previous VHDL code allows for easy parameteriation of s with arbitrary counts. Parametric VHDL code: The following VHDL code has a parameter COUNT. This is the my_genpulse.vhd code (Unit 5). library ieee; use ieee.std_logic_64.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; use ieee.math_real.log2.all; use ieee.math_real_ceil.all; entity my_genpulse is generic (COUNT: INTGR:= ); port (,, : in std_logic; Q: out std_logic_vector(integer(ceil(log2(real(count))))- downto ); : out std_logic); end my_genpulse; architecture bhv of my_genpulse is constant nbits:= INTGR:= integer(ceil(log2(real(count)))); signal Qt: std_logic_vector(nbits - downto );...
COUNTR DSIGN: PARAMTRIC COD This parametric is not only useful to generate pulses, but also to generate s with any arbitrary counts.... begin process (,,) begin if = '' then Qt <= (others => ''); elsif ('event and ='') then if = '' then if Qt = conv_std_logic_vector(count-,nbits) then Qt <= (others => ''); else Qt <= Qt + conv_std_logic_vector(,nbits); end if; end if; end if; end process; <= '' when Qt = conv_std_logic_vector (COUNT-, nbits) else ''; Q <= Qt; end bhv;
XAMPL: STOPWATCH Datapath design: A cascade interconnection allows the s to behave as desired. pause Counter modulo-6 C B A 4 QD 4 QC 4 QB 4 QA pause QA 2 3 4 5 6 7 8 9 2 3 3 4 5 A QB
XAMPL: STOPWATCH pause input: If the user asserts this input, the count must freee. This is achieved by using not(pause) to enable all the s. Note that it is possible to come up with this circuit by designing an FSM that controls the four enable inputs of the s. Timing diagram: note what needs to happen so that the third (QC) increments its count. pause QA 4 5 6 7 8 9 2 3 4 5 6 7 8 9 A QB 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 B QC
STOPWATCH DSIGN NXYS-4 Board: MH. Thus, the QA will increment its count every ns. We want QA to increment its count every.s ( ms). Straightforward solution: Change the input to H (period ms). This can be a hard problem if precise input is required. If we modify the frequency using s, we might have FPGA skew since the H will not go in the tree (among other problems). fficient solution: We use the that generates a pulse every ms. The output is then connected to every enable input of the s. This way, we get the same effect as modifying the frequency to H. The pulse is of duration of the input period ( ns). To generate a pulse every ms, we need a that counts up to (ms/ns) - = 6 -. Note that our generic with COUNT= 6 allows for a quick implementation of this circuit.
STOPWATCH DSIGN Datapath circuit: The figure shows the stopwatch with the up to 6 (named.s ). Note how the output of the.s is now connected to all the enables in the s. This way we make sure that every transition in the only occurs every. s ( ms) pause Counter (.s) Counter modulo-6 4 4 4 4
STOPWATCH DSIGN Datapath circuit: Final system with four 7-segment decoders so that the outputs can be seen in the displays. pause Counter (.s) Counter modulo-6 4 4 4 4 7-segment Decoder 7-segment Decoder 7-segment Decoder 7-segment Decoder 7 7 7 7
STOPWATCH DSIGN NXYS-4 Board: It has eight 7-segment displays, but all the displays share the same inputs. We can also enable (negative logic) a particular 7-segment display via the common anode (see Seven Display section in NXYS4 datasheet). Why do we have then eight 7-seg displays, if apparently all of them will display the same pattern? OUTPUT SRIALIZATION: With an enable for each 7-segment display, we can use one 7-segment display at a time. In order for each digit to appear bright and continuously illuminated, we illuminate each digit for only ms every 4 ms. We need only one 7-segment decoder, a Multiplexor, and an FSM that control the selector of the multiplexor. If we want the multiplexor selector to transition only ms every 4 ms, we connect the output of a new (to.s, COUNT = 5 ) to the enable input of the FSM. In our design, we only use four 7-segment displays.
STOPWATCH DSIGN pause Final Design: Datapath Circuit + FSM Counter (.s) S s = Counter modulo-6 S2 s 4 4 4 4 3 2 7-segment Decoder Counter (.s) S3 s 7 7 7 7 2 S4 s s N(3) N(2) N() N() N 4 2-to-4 decoder FSM
STOPWATCH DSIGN FSM Timing Diagram: state S S S S2 S2 S2 S2 S3 S3 S3 S3 S4 S4 s Xilinx IS Project: VHDL code: Instantiation (port map, generic map). For VHDL styling, see other units in VHDL for FPGAs Tutorial. Simulation: Testbench. If.s is omitted and =, we can easily simulate the circuit. dig_stopwatch.ip: Place-and-Route (pin assignment) FPGA programming and testing dig_stopwatch.vhd, my_genpulse.vhd, sevenseg.vhd, tb_dig_stopwatch.vhd, dig_stopwatch.ucf
US OF generic map Digital system design: many VHDL components available, some as parameteried VHDL code (for re-usability). So, when instantiating these components into a top-level file, we both map the signals (port map) and the parameters (generic map). StopWatch design: We need to instantiate five s. Parametric VHDL : my_genpulse.vhd. We have 3 s modulo-, modulo-6, and modulo- 6. Here, we must use generic map (see dig_stopwatch.vhd. We first declare my_genpulse.vhd in the top file:... architecture struct of dig_stopwatch is... component my_genpulse generic (COUNT: INTGR:= (**8)/2); port (,, : in std_logic; We copy what is in the entity of my_genpulse.vhd Q: out std_logic_vector(integer(ceil(log2(real(count))))- downto ); : out std_logic); end component;... begin...
US OF generic map The port map statement takes care of interconnecting the signals. The generic map statement maps the parameters. More than one parameter can be mapped. my_genpulse only has one parameter: generic map (parameter name in my_genpulse => parameter value in top file). Here, we have 5 s, each with a different count. If parameters are not mapped, the parameter values in the component declaration inside the architecture are assigned. This is not a good coding style: we might need to use a component more than once in the design, each time with different parameters.... g: my_genpulse generic map(count => **6) -- modulo- 6 port map( =>, =>, => npause, => ); g: my_genpulse generic map(count => ) -- port map( =>, =>, => npause, => ); g: my_genpulse generic map(count => ) -- port map( =>, =>, => npause, => ); g2: my_genpulse generic map(count => ) -- port map( =>, =>, => npause, => ); g3: my_genpulse generic map(count => 6) -- modulo-6 port map( =>, =>, => npause, => );... end struct;
XAMPL: LIGTHS PATTRN Configurable lights pattern generator: sel: selects pattern, stop: freees the pattern. X: selects the rate at which lights pattern change (every.5,.,.5, or.25 s) segs[7..] : 7 6 sel x 2 2 8 segs 5 4 stop? 2 3 sel
XAMPL: LIGTHS PATTRN ntire System: Q?? 2 x stop sel 2 (.5s) Q?? 2 FINIT STAT MACHIN dseg 8 sg D Q 8 7 7 On the NXYS4, only one 7-segment display can be used at a time 7 3 (.s) Counter (.s) Q?? FINIT STAT MACHIN s -to-2 decoder buf buf() buf() (.5s) Q?? x = Lights change every.5 s x = Lights change every. s x = Lights change every.5 s x = Lights change every.25 s (.25s)
XAMPL: LIGTHS PATTRN FSMs: S = sel S s = dseg, sg dseg, sg dseg, sg dseg, sg S2a S2b S2c S2d S2 s dseg, sg dseg, sg dseg, sg dseg, sg S3a S3b S3c S3d dseg, sg dseg, sg dseg, sg dseg, sg S4a S4b S4c S4d dseg, sg S6a dseg, sg S8a dseg, sg dseg, sg dseg, sg dseg, sg S5a dseg, sg S7a S5d S6d dseg, sg dseg, sg lights_pattern.ip: lights_pattern.vhd, my_genpulse.vhd, my_rege.vhd, tb_lights_pattern.vhd, lights_pattern.ucf dseg, sg
sclrq Q S LS MBDDING COUNTRS AND RGISTR IN ASM diagrams FSMs usually require s and registers for proper control. In VHDL code, this requires integrating the fsm description with port map/generic map to instantiate the s and registers. xample: digsys_ex: An FSM, a, a register, and a shift register. Asserting Q or sclrq can update the output Q, which can only be updated (Q, Q Q+) at the edge. For example: after asserting Q, we must wait until the edge for Q Q+. For the register, asserting D means that QD D on the next cycle. D 4 D Q 4 D QD FSM din L 3 Q sclr to 7 4 4 S Q LFT dout Q 4 QS SCLK FSM S S2 = SCLK Q Q, sclrq D, S, LS SCLK Q Q, sclrq Q (Q Q+) (Q ) (QD D, QS S) Q S (Q ) (Q Q+) (shift QS) Shift Register: S : After this signal is asserted, the shift register shifts data on the next cycle. S, LS : After these 2 signals are asserted, the shift register will load parallel data on the next cycle.
MBDDING COUNTRS AND RGISTR IN ASMs Timing diagram: digsys_ex. clk dig_sys_ex.ip: my_digsys_ex.vhd, my_genpulse_sclr.vhd, my_rege.vhd, my_pashiftreg.vhd, tb_digsys_ex.vhd. D S Q sclrq Q 2 3 4 5 6 7 2 3 4 5 6 7 Q state S S S S S S S S S S2 S2 S2 S2 S2 S2 S2 S2 S S SCLK D S LS QD QS
MBDDING COUNTRS AND RGISTR IN ASM diagrams Alternative coding style: we can embed s and registers inside the ASM description in VHDL (no need of port map). Note that the resulting circuit is not technically an FSM, since now some of the outputs are registered. For digsys_ex, only SCLK is now a combinational output. Procedure: Include the statements to infer s and registers in the State Transitions process. We need to clear their outputs when =. New circuit: It is functionally the same as the previous circuit, but the representation is different. D 4 QD S 4 4 FSMemb 4 SCLK QS FSMemb S S2 = SCLK Q=7 Q, QD D, QS S SCLK Q=7 Q Q+ These statements are executed on the edge Technically, not an FSM Q Q+ QS QSx2 Updated ASM Diagram (FSMemb): It is a bit misleading. The statements indicating updates to the, register, and shift register outputs do not take effect immediately, but rather on the immediate edge. So, even though this representation can be helpful, it can also be confusing. Q
MBDDING COUNTRS AND RGISTR IN ASM diagrams VHDL code: Use this coding style sparingly, as it is difficult to debug when there are too many inferred s and registers. The output signals QD, QS, sclk, behave exactly the same as in the original digsys_ex circuit (the one with FSM and port map/generic map). library ieee; Note that Q is defined as an integer to simplify coding. QSt: we need this auxiliary signal as we cannot feedback the output QS back to the circuit (we need this for shifting). use ieee.std_logic_64.all; use ieee.std_logic_unsigned.all; entity digsys_ex is port (, : in std_logic; D,S: in std_logic_vector(3 downto ); QD,QS: out std_logic_vector(3 downto ); sclk: out std_logic); end digsys_ex; dig_sys_exp.ip: my_digsys_ex.vhd, tb_digsys_ex.vhd. architecture bhv of digsys_ex is type state is (S, S2); signal y: state; signal Q: integer range to 7; signal QSt: std_logic_vector(3 downto ); begin...
MBDDING COUNTRS AND RGISTR IN ASM diagrams Note how easy it is to update a, a register, or shift register. Do not forget to assign the values on reset. This avoids having to use port map instructions.... Transitions: process (, ) begin if = '' then -- asynchronous signal y <= S; QD<=""; Q <= ; QSt<="" -- values on reset elsif ('event and ='') then case y is when S => if Q=7 then y<=s2; Q<=; QD <= D; QSt <= S; else y<=s; Q <= Q+; end if; when S2 => if Q=7 then y<=s; Q<=; else y<=s2; Q <= Q+; QSt() <= ''; QSt(3 downto ) <= QSt(2 downto ); end if; end case; end if; end process; Q <= QSt; Outputs: process (y,q) begin sclk <= ''; case y is when S => when S2 => sclk <= ''; end case; end process; end bhv;