Control Unit Example
From JavierValcarce.Es
Summary
Example of a control unit specified in a compact and readable form. This is the form in which all control units are described in VHDL at this site.
Contents |
Control Unit
The usual form to describe a syncronous sequential system to control[1] a datapath is using two VHDL processes:
- One sequential, that stores the state and evolves thought the graph's states.
- One combinational, that decodes the state and generates the control signals for the datapath. This control signals are not registered so they can have spurious transitions (be aware when interfacing external not syncronous devices).
Sequential Process
-- Sequential. Transitions between states process (reset, clk) begin if reset = '1' then state <= e0; elsif rising_edge(clk) then -- Graph transitions -- case (state) is when e0 => state <= e1a; when e1a => state <= e1b; when e1b => if x1 = '1' then state <= e2a; end if; when e2a => state <= e2b; when e2b => if x2 = '1' then state <= e3a; end if; when e3a => state <= e3b; when e3b => if x3 = '1' then state <= e4a; end if; when e4a => state <= e4b; when e4b => if x4 = '1' then state <= e5a; end if; when e5a => state <= e5b; when e5b => if x5 = '1' then state <= e6; end if; when e6 => if x6 = '1' then state <= e0; else state <= e2a; end if; end case; end if; end process;
Combinatorial Process
-- Combinatorical process -- This variable is for group all datapath's control signals -- in array op to obtain code more compact and readable code -- variable op : std_logic_vector(6 downto 0); process (state) begin case state is when e0 => op <= STRTRIM("00000 10"); when e1a => op <= STRTRIM("10000 00"); when e1b => op <= STRTRIM("00000 00"); when e2a => op <= STRTRIM("01000 00"); when e2b => op <= STRTRIM("00000 00"); when e3a => op <= STRTRIM("00100 00"); when e3b => op <= STRTRIM("00000 00"); when e4a => op <= STRTRIM("00010 00"); when e4b => op <= STRTRIM("00000 00"); when e5a => op <= STRTRIM("00001 01"); when e5b => op <= STRTRIM("00000 00"); when e6 => op <= STRTRIM("00000 00"); end case; end process; -- 7 control example signals, unpack them vga_req <= op(06); window_req <= op(05); fourier_req <= op(04); periodogram_req <= op(03); average_req <= op(02); ctr_rst <= op(01); ctr_ce <= op(00);
Utils Package
Contains the STRTRIM funcion used above. Include use work.utils.all; in your VHDL code.
library IEEE; use IEEE.STD_LOGIC_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_signed.all; package utils is -- Elimina todos los espacios de una cadena y construye un std_logic_vector -- con los elementos restantes, que deben ser '0', '1' o bien '-' function STRTRIM(s : string) return std_logic_vector; end utils; package body utils is function STRTRIM(s : string) return std_logic_vector is alias sv : string(1 to s'length) is s; variable res : std_logic_vector(1 to sv'length); variable i, j : natural; begin j := 0; for i in 1 to sv'length loop case sv(i) is when '0' => j := j + 1; res(j) := '0'; when '1' => j := j + 1; res(j) := '1'; when '-' => j := j + 1; res(j) := '-'; when ' ' => null; when others => assert (false) report "Utils.STRTRIM: Bad Format" severity failure; end case; end loop; return res(1 to j); end function STRTRIM; end utils;