Guest User

FSM

a guest
Jun 27th, 2018
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VHDL 8.16 KB | None | 0 0
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3.  
  4. entity FSM is
  5. port(
  6.     clk: in std_logic;
  7.     areset: in std_logic;
  8.     valid: in std_logic;
  9.     input: in std_logic;
  10.     output: out std_logic
  11. );
  12. end FSM;
  13.  
  14. architecture arch of FSM is
  15.  
  16. -- declaring states
  17. -- RESET -> startup state and resetting
  18. -- WRITEA -> writing the vector A
  19. -- CALC -> calculating state (reading A and H, calculating result and writing result into R)
  20. -- READR -> reading the result from vector R
  21. type state_type is (RESET, WRITEA, CALC, READR);
  22. signal state: state_type;
  23.  
  24. -- components
  25. component ramA is
  26. generic(
  27.     address_length: natural := 2
  28. );
  29. port(
  30.     clk: in std_logic;
  31.     rw_enable: in std_logic;
  32.     mem_enable: in std_logic;
  33.     address: in std_logic_vector((address_length - 1) downto 0);
  34.     data_input: in std_logic;
  35.     data_output: out std_logic
  36. );
  37. end component;
  38.  
  39. component counterA is Generic(
  40.     count_width : natural := 2
  41. );
  42. port(
  43.     clk: in std_logic;
  44.     reset: in std_logic;
  45.     count_enable: in std_logic;
  46.     count: out std_logic_vector(count_width-1 downto 0)
  47. );
  48. end component;
  49.  
  50. component romH is
  51. generic(
  52.     address_length: natural := 3
  53. );
  54. port(
  55.     clk: in std_logic;
  56.     rom_enable: in std_logic;
  57.     address: in std_logic_vector((address_length - 1) downto 0);
  58.     data_output: out std_logic
  59. );
  60. end component;
  61.  
  62. component counterH is Generic(
  63.     count_width : natural := 3
  64. );
  65. port(
  66.     clk: in std_logic;
  67.     reset: in std_logic;
  68.     count_enable: in std_logic;
  69.     count: out std_logic_vector(count_width-1 downto 0)
  70. );
  71. end component;
  72.  
  73. component accumulator is
  74. port(
  75.     clk: in std_logic;
  76.     reset: in std_logic;
  77.     input1: in std_logic;
  78.     input2: in std_logic;
  79.     output: out std_logic
  80. );
  81. end component;
  82.  
  83. component ramR is
  84. generic(
  85.     address_length: natural := 1
  86. );
  87. port(
  88.     clk: in std_logic;
  89.     rw_enable: in std_logic;
  90.     mem_enable: in std_logic;
  91.     address: in std_logic_vector((address_length - 1) downto 0);
  92.     data_input: in std_logic;
  93.     data_output: out std_logic
  94. );
  95. end component;
  96.  
  97. component counterR is Generic(
  98.     count_width : natural := 1
  99. );
  100. port(
  101.     clk: in std_logic;
  102.     reset: in std_logic;
  103.     count_enable: in std_logic;
  104.     count: out std_logic_vector(count_width-1 downto 0)
  105. );
  106. end component;
  107.  
  108.  
  109. -- declaring signals
  110. signal count_addressA : std_logic_vector(2-1 downto 0); -- signal to connect counterA with ramA (non-generic!)
  111. signal count_addressH : std_logic_vector(3-1 downto 0); -- signal to connect counterH with romH (non-generic!)
  112. signal count_addressR : std_logic_vector(1-1 downto 0); -- signal to connect counterR with ramR (non-generic!)
  113.  
  114. signal rw_enableA, mem_enableA, count_resetA, count_enableA : std_logic; --control signals for ramA and counterA
  115. signal rom_enableH, count_resetH, count_enableH : std_logic; -- control signals for romH and counterH
  116. signal accumulator_reset : std_logic; -- control signal of accumulator
  117. signal rw_enableR, mem_enableR, count_resetR, count_enableR : std_logic; --control signals for ramR and counterR
  118.  
  119. signal output_A, output_H : std_logic; -- outputs of ramA and romH
  120. signal output_accum : std_logic; -- output of accumulator to connect with ramR input
  121.  
  122. begin
  123.  
  124. -- port mapping of components
  125. U1: ramA port map(
  126.     clk => clk,
  127.     rw_enable => rw_enableA,
  128.     mem_enable => mem_enableA,
  129.     address => count_addressA,
  130.     data_input => input,
  131.     data_output => output_A
  132. );
  133.  
  134. U2: counterA port map(
  135.     clk => clk,
  136.     reset => count_resetA,
  137.     count_enable => count_enableA,
  138.     count => count_addressA
  139. );
  140.  
  141. U3: romH port map(
  142.     clk => clk,
  143.     rom_enable => rom_enableH,
  144.     address => count_addressH,
  145.     data_output => output_H
  146. );
  147.  
  148. U4: counterH port map(
  149.     clk => clk,
  150.     reset => count_resetH,
  151.     count_enable => count_enableH,
  152.     count => count_addressH
  153. );
  154.  
  155. U5: accumulator port map(
  156.     clk => clk,
  157.     reset => accumulator_reset,
  158.     input1 => output_A,
  159.     input2 => output_H,
  160.     output => output_accum
  161. );
  162.  
  163. U6: ramR port map(
  164.     clk => clk,
  165.     rw_enable => rw_enableR,
  166.     mem_enable => mem_enableR,
  167.     address => count_addressR,
  168.     data_input => output_accum,
  169.     data_output => output -- main output of the circuit
  170. );
  171.  
  172. U7: counterR port map(
  173.     clk => clk,
  174.     reset => count_resetR,
  175.     count_enable => count_enableR,
  176.     count => count_addressR
  177. );
  178.  
  179. -- processes
  180. state_transition: process(clk, areset)
  181. begin
  182.     -- asynchronous reset
  183.     if(areset = '1') then
  184.         state <= RESET;
  185.     -- state transitioning
  186.     elsif(rising_edge(clk)) then
  187.         case state is
  188.             when RESET =>
  189.                 if(areset = '0') then
  190.                     state <= WRITEA;
  191.                 end if;
  192.            
  193.             when WRITEA =>
  194.                 if(count_addressA = "11") then -- after the last item of A!
  195.                     state <= CALC;
  196.                 end if;
  197.            
  198.             when CALC =>
  199.                 if(count_addressH = "111") then -- after the last item of H!
  200.                     state <= READR;
  201.                 end if;
  202.            
  203.             when READR =>
  204.                 if(count_addressR = "1") then -- after the last item of R!
  205.                     state <= RESET;
  206.                 end if;
  207.         end case;
  208.     end if;
  209.  
  210. end process;
  211.  
  212. output_process: process(state, valid, count_addressA)
  213. -- the valid signal changes the behavior of the 'WRITEA' state
  214. -- the count_addressA signal changes the behavior of the 'CALC' state
  215. begin
  216.     case state is
  217.         when RESET =>
  218.             -- disable ramA
  219.             rw_enableA <= '1';
  220.             mem_enableA <= '0';
  221.            
  222.             -- reset counterA
  223.             count_resetA <= '1';
  224.             count_enableA <= '0';
  225.            
  226.             -- disable romH
  227.             rom_enableH <= '0';
  228.            
  229.             -- reset counterH
  230.             count_resetH <= '1';
  231.             count_enableH <= '0';
  232.            
  233.             -- reset accumulator
  234.             accumulator_reset <= '1';
  235.            
  236.             -- disable ramR
  237.             rw_enableR <= '1';
  238.             mem_enableR <= '0';
  239.            
  240.             -- reset counterR
  241.             count_resetR <= '1';
  242.             count_enableR <= '0';
  243.        
  244.         when WRITEA =>
  245.             -- set ramA into reading mode
  246.             rw_enableA <= '1';
  247.            
  248.             -- make sure that the counters are not in reset anymore
  249.             count_resetA <= '0';
  250.             count_resetH <= '0';
  251.             count_resetR <= '0';
  252.            
  253.             -- keep accumulator in reset to not get 'U' signal
  254.             accumulator_reset <= '1';
  255.            
  256.             -- H and R are not needed (romH managed separately)
  257.             count_enableH <= '0';
  258.             count_enableR <= '0';
  259.             rw_enableR <= '1';
  260.             mem_enableR <= '0';
  261.            
  262.             -- input depends on the valid signal
  263.             if(valid = '1') then -- valid input
  264.                 mem_enableA <= '1';
  265.                 count_enableA <= '1';
  266.             else -- non-valid input
  267.                 mem_enableA <= '0';
  268.                 count_enableA <= '0';
  269.             end if;
  270.            
  271.             if(count_addressA /= "11") then -- manage romH
  272.                 rom_enableH <= '1';
  273.             else
  274.                 rom_enableH <= '0';
  275.             end if;
  276.        
  277.         when CALC =>
  278.             if(count_addressA /= "11") then -- only calculating
  279.                 -- enable ramA for reading
  280.                 rw_enableA <= '0';
  281.                 mem_enableA <= '1';
  282.                
  283.                 -- enable counterA
  284.                 count_enableA <= '1';
  285.                 count_resetA <= '0';
  286.                
  287.                 --enable romH for reading
  288.                 rom_enableH <= '1';
  289.                            
  290.                 -- enable counterH
  291.                 count_enableH <= '1';
  292.                 count_resetH <= '0';
  293.                
  294.                 -- make sure accumulator is not in reset anymore
  295.                 accumulator_reset <= '0';
  296.                
  297.                 -- make sure  ramR and counterR are disabled
  298.                 rw_enableR <= '1';
  299.                 mem_enableR <= '0';
  300.                 count_resetR <= '0';
  301.                 count_enableR <= '0';
  302.                
  303.             else -- calculating storing result
  304.                 -- keep ramA reading
  305.                 rw_enableA <= '0';
  306.                 mem_enableA <= '1';
  307.                
  308.                 -- keep counterA active
  309.                 count_enableA <= '1';
  310.                 count_resetA <= '0';
  311.                
  312.                 --keep romH reading
  313.                 rom_enableH <= '1';
  314.                
  315.                 -- keep counterH active
  316.                 count_enableH <= '1';
  317.                 count_resetH <= '0';
  318.                
  319.                 -- reset accumulator (that will happen in the next cycle)
  320.                 accumulator_reset <= '1';
  321.                
  322.                 -- enable ramR for writing (so that it writes in the next cycle)
  323.                 rw_enableR <= '1';
  324.                 mem_enableR <= '1';
  325.                
  326.                 -- enable counterR (so that it increments in the next cycle)
  327.                 count_resetR <= '0';
  328.                 count_enableR <= '1';
  329.             end if;
  330.        
  331.         when READR =>
  332.             -- disable ramA
  333.             mem_enableA <= '0';
  334.             rw_enableA <= '0';
  335.            
  336.             -- disable counterA
  337.             count_enableA <= '0';
  338.             count_resetA <= '0';
  339.            
  340.             -- disable romH
  341.             rom_enableH <= '0';
  342.            
  343.             -- disable counterH
  344.             count_enableH <= '0';
  345.             count_resetH <= '0';
  346.  
  347.             -- reset accumulator
  348.             accumulator_reset <= '1';
  349.            
  350.             -- enable ramR for reading
  351.             rw_enableR <= '0';
  352.             mem_enableR <= '1';
  353.            
  354.             -- enable counterR
  355.             count_resetR <= '0';
  356.             count_enableR <= '1';  
  357.            
  358.     end case;
  359. end process;
  360.  
  361. end arch;
Add Comment
Please, Sign In to add comment