Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- library ieee;
- use ieee.std_logic_1164.all;
- entity system_core is
- port(
- num : in std_logic_vector(7 downto 0); --ulazni broj koji ucitavamo (prvo je a a onda b)
- next_num : in std_logic;
- plus : in std_logic;
- minus : in std_logic;
- clk : in std_logic;
- reset : in std_logic; -- aktivan na logicku nulu
- display_num : out std_logic_vector(7 downto 0) --izlazni broj koji svetli
- );
- end system_core;
- architecture system_core_behav of system_core is
- type state_type is (init, read_a, read_b, add, sub); --stanja
- signal state_reg, next_state : state_type;
- signal timeout_cnt : integer range 0 to 20 :=0; --indeks brojaca koji broji kolko jos treba cekati
- signal isteklo : std_logic := '0'; -- true/false dal je vreme isteklo. znaci uporedjujemo brojace sa 10 pa ako je jednako onda je isteklo='1' pa se deava nesto
- signal a : std_logic_vector(7 downto 0); -- ko sto smo imali sumu u automatu tako i ovde neki signal u koji pamtimo
- signal b : std_logic_vector(7 downto 0);
- signal sel : std_logic; -- ovaj ce da sluzi za biranje oduz/sab jer nas add_sub_4b se podesava sa sel (1 signal) a ovde imamo 2 pa treba to regulisati
- signal result : std_logic_vector(7 downto 0); --ovde se pamti rezultat pa se stavi na izlaz
- component add_sub_4bit is
- port
- (
- a : in std_logic_vector(7 downto 0);
- b : in std_logic_vector(7 downto 0);
- sel : in std_logic; -- ADD if '0', SUB if '1'
- s : out std_logic_vector(7 downto 0)
- );
- end component;
- begin
- --sekv kako se menjaju stanja
- state_transition : process (clk, reset)
- begin
- if (reset = '0') then
- state_reg <= init;
- elsif (rising_edge(clk)) then
- state_reg <= next_state;
- end if;
- end process state_transition;
- --komb kakav je izlaz u kom stanju
- display_logic : process (state_reg, num, result)
- begin
- if (state_reg = init) then
- display_num <= "00000000";
- elsif (state_reg = read_a) then
- display_num <= num;
- elsif (state_reg = read_b) then
- display_num <= num;
- else
- display_num <= result; --u result u zavisnosti od stanja stavljamo sab/oduz pa on ovde ni ne razmislja o tome sta je to
- end if;
- end process display_logic;
- -- komb odredjuje next_state na osnovu prethodnog stanja i ulaza
- next_state_logic : process (state_reg, next_num, isteklo, plus, minus)
- begin
- next_state <= state_reg;
- case (state_reg) is
- when init =>
- if next_num = '1' then
- next_state <= read_a; --inace je next_state <= state_reg; zato to pisemo na pocetku
- end if;
- when read_a =>
- if next_num = '1' then
- next_state <= read_b;
- end if;
- when read_b =>
- if plus = '1' then
- next_state <= add; --za svaki if je next_state <= state_reg; else grana!!
- elsif minus ='1' then
- next_state <= sub;
- end if;
- when add =>
- if isteklo = '1' then
- next_state <= init;
- end if;
- when sub =>
- if isteklo = '1' then
- next_state <= init;
- end if;
- end case;
- end process next_state_logic;
- --sekv upravlja add_sub_4bit ,postavlja sel u zavisnosti od koje je next_state
- sel_logic : process(clk, reset)
- begin
- if (reset = '0') then
- sel <= '0';
- elsif (rising_edge(clk)) then
- if (next_state = add) then
- sel <= '0';
- elsif (next_state = sub) then
- sel <= '1';
- end if;
- end if;
- end process sel_logic;
- --sekv ucitavanjec pomocnih signala a i b u zavisnosti od clk i sta je num u read_a i read_b
- load_a_b : process(clk, reset)
- begin
- if (reset = '0') then
- a <= "00000000";
- b <= "00000000";
- elsif (rising_edge(clk)) then
- if (state_reg = read_a and next_state = read_b) then --znaci da je pre uzlazne ivice clk , next_num vec potao 1 , ako nije ceka se na to pre promene
- a <= num;
- elsif (state_reg = read_b and (next_state = add or next_state = sub)) then
- b <= num;
- end if;
- end if;
- end process load_a_b;
- --definisi preslikavanje ulaza i izlaza
- ADDSUB4B : add_sub_4bit port map (
- a => a,
- b => b,
- sel => sel,
- s=> result
- );
- --sekv brojac povecava timeout_cnt dok smo u add ili sub za svaki takt, kada predjemo u init brojanje je resetuje
- --u sustini brojac broji koliko smo taktova ostali u stanju koje prikazuje na izlazu rezultat
- cnt_process: process(state_reg, clk)
- variable cnt : integer range 0 to 20;
- begin
- if (state_reg = init) then
- cnt := 0;
- elsif (state_reg = add or state_reg = sub) then
- if(rising_edge(clk)) then
- cnt := cnt + 1;
- end if;
- end if;
- timeout_cnt <= cnt;
- end process cnt_process;
- --komb postavljanje u zavisnosti od timeout_cnt dal je isteklo='1'
- isteci: process(timeout_cnt)
- begin
- if (timeout_cnt=10) then
- isteklo <= '1';
- else
- isteklo <= '0';
- end if;
- end process isteci;
- end system_core_behav;
- test bench:
- LIBRARY ieee;
- USE ieee.std_logic_1164.all;
- ENTITY system_core_vhd_tst IS
- END system_core_vhd_tst;
- ARCHITECTURE system_core_arch OF system_core_vhd_tst IS
- -- constants
- constant clk_period: time :=20 ns;
- -- signals
- SIGNAL clk : STD_LOGIC;
- SIGNAL display_num : STD_LOGIC_VECTOR(7 DOWNTO 0);
- SIGNAL minus : STD_LOGIC;
- SIGNAL next_num : STD_LOGIC;
- SIGNAL num : STD_LOGIC_VECTOR(7 DOWNTO 0);
- SIGNAL plus : STD_LOGIC;
- SIGNAL reset : STD_LOGIC;
- COMPONENT system_core
- PORT (
- clk : IN STD_LOGIC:='0';
- display_num : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
- minus : IN STD_LOGIC:='0';
- next_num : IN STD_LOGIC:='0';
- num : IN STD_LOGIC_VECTOR(7 DOWNTO 0):="00000000";
- plus : IN STD_LOGIC:='0';
- reset : IN STD_LOGIC:='1'
- );
- END COMPONENT;
- BEGIN
- i1 : system_core
- PORT MAP (
- -- list connections between master ports and signals
- clk => clk,
- display_num => display_num,
- minus => minus,
- next_num => next_num,
- num => num,
- plus => plus,
- reset => reset
- );
- clk_gen : PROCESS
- -- variable declarations
- BEGIN
- wait for clk_period/2;
- clk<='0';
- wait for clk_period/2;
- clk<='1';
- END PROCESS clk_gen;
- always : PROCESS
- BEGIN
- minus<='0';
- plus<='0';
- next_num<='0';
- num<="10000001";
- reset<='0';
- wait for clk_period*3;
- reset<='1';
- next_num<='1';
- wait for clk_period;
- next_num<='0';
- wait for 3*clk_period;
- num<="00000001";
- next_num<='1';
- wait for clk_period;
- next_num<='0';
- wait for 2*clk_period;
- plus<='1';
- wait for clk_period;
- plus<='0';
- WAIT;
- END PROCESS always;
- END system_core_arch;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement