Synthese av VHDL - Oppdatert

From ift
Revision as of 12:26, 24 March 2016 by Ogr043 (talk | contribs) (Created page with "===Syntetiseringen av VHDL kode=== Vi ønsker å syntisere koden for å lage beskrivelse av koden tilpasset en FPGA-chip. Vi skal først syntisere koden med Quartus. Deretter...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Syntetiseringen av VHDL kode

Vi ønsker å syntisere koden for å lage beskrivelse av koden tilpasset en FPGA-chip. Vi skal først syntisere koden med Quartus. Deretter skal vi simulere denne koden og sammenligne med den opprinnelige koden uten timing-informasjon. Vi bruker en ALU som eksempel.

Det er viktig at vi bruker Quartus og ModelSim fra samme utgivelse om vi ikke ønsker å kompilere våre egne simuleringsbibliotek. Du kan installere Quartus og ModelSim gratis og bruke lisens-server på UiB sitt nettverk. Vi bruker Quartus Prime 15.1 og ModelSim 10.4b.

Quartus

Lag et nytt prosjekt, kall det add_sub_alu og velg en passende mappe. Velg empty project, og deretter legg til add_sub_alu.vhd. Velg en CycloneV-chip. Vi valgte 5CSEMA5F31C6. Det er chipen på Terasic DE1-SoC. Pass på at add_sub_alu.vhd er valgt som top-level og trykk så Start Compilation (Ctrl-L). Dette gjør at Quartus går gjennom alle stegene for å produsere filene vi er ute etter.

Modelsim

Simulering med timing

Konklusjon

Kode

Kode til add_sub_alu.vhdl

LIBRARY ieee;
USE ieee.std_logic_1164.All;
USE ieee.std_logic_unsigned.all;

ENTITY add_sub_alu IS
  PORT (clk, rst    : IN  std_logic;
  enable_in   : IN  std_logic;
  start       : IN  std_logic;
  enable      : IN  std_logic;
  do_add      : IN  std_logic;
  do_subtract : IN  std_logic;
  do_hold     : IN  std_logic;
  data_in     : IN  std_logic_vector(3 DOWNTO 0);
  data_out    : OUT std_logic_vector (3 DOWNTO 0) BUS);
END add_sub_alu;

ARCHITECTURE algorithm OF add_sub_alu IS
TYPE states IS (hold, reset, add, subtract);
SIGNAL state_var : states;
SIGNAL reg, int_reg : std_logic_vector(3 DOWNTO 0);
SIGNAL latched_data_in: std_logic_vector(3 DOWNTO 0);
BEGIN

latch: PROCESS (enable_in, data_in)is
BEGIN
IF (enable_in = '1') THEN
latched_data_in <= data_in;
END IF;
END PROCESS latch;

fsm: PROCESS (clk, rst) is
BEGIN
IF (rst = '0') THEN
state_var <= reset;
ELSIF (clk'EVENT AND clk = '1') THEN
CASE state_var IS
WHEN hold     => IF (start = '1') THEN
state_var <= reset;
END IF;
WHEN reset    => IF (do_add = '1') THEN
state_var <= add;
ELSIF (do_subtract = '1') THEN
state_var <= subtract;
END IF;
WHEN add      => IF (do_hold = '1') THEN
state_var <= hold;
ELSIF (do_subtract = '1') THEN
state_var <= subtract;
END IF;
WHEN subtract => IF (do_hold = '1') THEN
state_var <= hold;
ELSIF (do_add = '1') THEN
state_var <= add;
END IF;
WHEN OTHERS => state_var <= reset;
END CASE;
END IF;
END PROCESS fsm;

alu: PROCESS (state_var, latched_data_in, reg)is
BEGIN
CASE state_var IS
WHEN add      => int_reg <= reg + latched_data_in;
WHEN subtract => int_reg <= reg - latched_data_in;
WHEN reset    => int_reg <= "0000";
WHEN hold     => int_reg <= reg;
WHEN OTHERS   => int_reg <= reg;
END CASE;
END PROCESS alu;

mem: PROCESS (clk) is
BEGIN
IF (clk'EVENT AND clk = '1') THEN
reg <= int_reg;
END IF;
END PROCESS mem;

tri: PROCESS (enable, reg) is
BEGIN
FOR i IN 3 DOWNTO 0 LOOP
IF (enable = '1') THEN
data_out(i) <= reg(i);
ELSE
data_out(i) <= 'Z';
END IF;
END LOOP;
END PROCESS tri;

END algorithm;

Koden til alu_tb.vhdl

library ieee;
use ieee.std_logic_1164.all;
library work;
use work.all;

entity alu_tb is
end entity alu_tb;

architecture struct of alu_tb is
--Deklaring av signal som skal koblast til komponentane.
--Alle innsignal er felles, medan vi har 2 forskjellige utsignal.
signal clk, reset : std_logic;
signal enable_in : std_logic;
signal start : std_logic;
signal enable : std_logic;
signal do_add : std_logic;
signal do_subtract : std_logic;
signal do_hold : std_logic;
signal data_in : std_logic_vector(3 downto 0);
signal data_out : std_logic_vector(3 downto 0);
signal data_out_synt : std_logic_vector(3 downto 0);

begin

--Deklarer komponenten alu.
alu : entity add_sub_alu(algorithm)

--Kobler signala til den opprinnelige komponenten.
port map (
clk => clk,
rst => reset,
enable_in => enable_in,
start => start,
enable => enable,
do_add => do_add,
do_subtract => do_subtract,
do_hold => do_hold,
data_in => data_in,
data_out => data_out);

--Deklarer komponenten alu_synt.
alu_synt : entity add_sub_alu_synth(structure)

--Kobler signala til den synthiserte komponenten.
port map (
clk => clk,
rst => reset,
enable_in => enable_in,
start => start,
enable => enable,
do_add => do_add,
do_subtract => do_subtract,
do_hold => do_hold,
data_in => data_in,
data_out => data_out_synt);

--Klokkegenerator
clock_gen : process
begin
clk <= '0', '1' after 50 ns;
wait for 100 ns;
end process clock_gen;

--Setter testvektorane.
reset <= '0', '1' after 60 ns;
enable <= '1', '0' after 900 ns;
enable_in <= '1', '0' after 400 ns;
start <= '1', '0' after 300 ns;
do_add <= '1', '0' after 660 ns;
do_subtract <= '0';
do_hold <= '0';
data_in <= X"3";

--Test process for å samanlikne utsignala kvart nanosekund.
test : process
begin
wait for 1 ns;
assert (data_out = data_out_synt)
report "Data ut er ulik"
severity Error;
end process test;

end;