library IEEE; library UNISIM; use IEEE.std_logic_1164.all; use UNISIM.Vcomponents.all; entity STATEMACHINE4 is port( CLK : in std_logic; DATAOUTA : out std_logic_vector(7 downto 0) ); end STATEMACHINE4; architecture RTL of STATEMACHINE4 is component ALU port( A,B : in std_logic_vector(31 downto 0); CODE : in std_logic_vector(5 downto 0); DOUT : out std_logic_vector(31 downto 0); Z : out std_logic ); end component; component PC port( PCINDATA : in std_logic_vector(8 downto 0); PCOUTDATA : out std_logic_vector(8 downto 0); PCCLK : in std_logic; PCWRITE_EN : in std_logic; PCRESET : in std_logic ); end component; component PC_INCREMENTER port( PCIINDATA : in std_logic_vector(8 downto 0); PCIOUTDATA : out std_logic_vector(8 downto 0) ); end component; component SELECTOR port( A : in std_logic_vector(8 downto 0); B : in std_logic_vector(8 downto 0); SEL : in std_logic; OUTDATA : out std_logic_vector(8 downto 0) ); end component; component SELECTOR2 port( A : in std_logic_vector(31 downto 0); B : in std_logic_vector(31 downto 0); SEL : in std_logic; OUTDATA : out std_logic_vector(31 downto 0) ); end component; component ANDGATE port( A,B : in std_logic; C : out std_logic ); end component; type STATE is (INIT,FETCHA,FETCHB,DECODE,DECODE2,EX,WB,FIN); signal CURRENT_STATE,NEXT_STATE : STATE; signal ALUOP : std_logic_vector(5 downto 0); signal ALUINA,ALUINB,ALUOUT : std_logic_vector(31 downto 0); signal ADA,ADB,SIGPC_OUT,SIGPCIOUTDATA : std_logic_vector(8 downto 0); signal ZFLAG,ENAA,ENAA2,ENAB,RESA,RESA2,RESB,WENA,WENA2,WENB,SIGPCRESET,SIGPCWRITE_EN : std_logic; signal DAIA,DAIA2,DAIB : std_logic_vector(31 downto 0); signal DPA,DPA2,DPB : std_logic_vector(3 downto 0); signal DAOA,DAOA2,DAOB : std_logic_vector(31 downto 0); signal SIGJUMP,SIGBRANCH,SIGIMMEDIATE,SEL2IN : std_logic; signal SEL3INA,IMMEDIATE : std_logic_vector(31 downto 0); signal JUMPTARGET,BRANCHTARGET,SIGPCIN,SEL2OUT : std_logic_vector(8 downto 0); begin ALU0 : ALU port map( A =>ALUINA, B =>ALUINB, CODE=>ALUOP, DOUT=>ALUOUT, Z =>ZFLAG ); PC0 : PC port map( PCINDATA => SIGPCIN, PCOUTDATA => SIGPC_OUT, PCCLK => CLK, PCRESET => SIGPCRESET, PCWRITE_EN => SIGPCWRITE_EN ); PCI0 : PC_INCREMENTER port map( PCIINDATA => SIGPC_OUT, PCIOUTDATA => SIGPCIOUTDATA ); SEL1 : SELECTOR port map( A => SEL2OUT, B => JUMPTARGET, SEL => SIGJUMP, OUTDATA => SIGPCIN ); SEL2 : SELECTOR port map( A => SIGPCIOUTDATA, B => BRANCHTARGET, SEL => SEL2IN, OUTDATA => SEL2OUT ); SEL3 : SELECTOR2 port map( A => SEL3INA, B => IMMEDIATE, SEL => SIGIMMEDIATE, OUTDATA => ALUINB ); AND0 : ANDGATE port map( A => ZFLAG, B => SIGBRANCH, C => SEL2IN ); INSTMEM : RAMB16_S36 generic map( WRITE_MODE => "WRITE_FIRST", -- initialize instruction memory -- addr:000000000 LOOP1:beq r1,r2,RET1 -- addr:000000001 add r4,r3,r4 -- addr:000000010 addi r2,r2,1 -- addr:000000011 jump LOOP2 -- addr:000000100 LOOP2:beq r1,r2,RET2 -- addr:000000101 add r3,r3,r4 -- addr:000000110 addi r2,r2,1 -- addr:000000111 jump LOOP1 INIT_00 => X"180000000C4200010464180014220009180000040C4200010464200014220008", -- addr:000001000 RET1 :mr r5,r3 -- addr:000001001 RET2 :mr r5,r4 INIT_01 => X"0000000000000000200000001CA0000010850000200000001CA0000010650000" ) port map ( ADDR=>SIGPC_OUT, CLK =>CLK, EN =>ENAA2, SSR =>RESA2, WE =>WENA2, DI =>DAIA2, DIP =>DPA2, DO =>DAOA2 ); REGFILE : RAMB16_S36_S36 generic map( WRITE_MODE_A => "WRITE_FIRST", WRITE_MODE_B => "WRITE_FIRST", -- initialize register -- addr:000000001 r1=10 -- addr:000000010 r2=1 -- addr:000000011 r3=1 -- addr:000000100 r4=0 INIT_00 => X"0000000000000000000000000000000000000001000000010000000B00000000" ) port map ( ADDRA=>ADA, ADDRB=>ADB, CLKA =>CLK, CLKB =>CLK, ENA =>ENAA, ENB =>ENAB, SSRA =>RESA, SSRB =>RESB, WEA =>WENA, WEB =>WENB, DIA =>DAIA, DIB =>DAIB, DIPA =>DPA, DIPB =>DPB, DOA =>DAOA, DOB =>DAOB ); process(CLK) begin if(CLK'event and CLK='1') then CURRENT_STATE <= NEXT_STATE; end if; end process; process(CURRENT_STATE,DAOA,DAOB,DAOA2) begin case CURRENT_STATE is when INIT => SIGPCWRITE_EN <= '0'; SIGPCRESET <= '1'; ENAA2 <= '1'; WENA2 <= '0'; NEXT_STATE <= DECODE; when FETCHA => -- read from program counter, write instruction to IR SIGPCRESET <= '0'; SIGPCWRITE_EN <= '0'; SIGJUMP <= '0'; SIGBRANCH <= '0'; SIGIMMEDIATE <= '0'; ENAA2 <= '1'; WENA2 <= '0'; NEXT_STATE <= FETCHB; when FETCHB => NEXT_STATE <= DECODE; when DECODE => SIGPCRESET <= '0'; RESA <= '0'; RESB <= '0'; ENAA <= '1'; ENAB <= '1'; WENA <= '0'; WENB <= '0'; if(DAOA2(31 downto 26) = "000110") then --jump JUMPTARGET <= DAOA2(8 downto 0); SIGJUMP <= '1'; NEXT_STATE <= DECODE2; elsif(DAOA2(31 downto 26) = "000101") then --beq(branch on equal) BRANCHTARGET <= DAOA2(8 downto 0); SIGJUMP <= '0'; SIGBRANCH <= '1'; SIGIMMEDIATE <= '0'; ADA <= "0000"&DAOA2(25 downto 21); ADB <= "0000"&DAOA2(20 downto 16); ALUOP <= "000010"; NEXT_STATE <= DECODE2; elsif(DAOA2(31 downto 26) = "000011") then --addi IMMEDIATE <= "0000000000000000"&DAOA2(15 downto 0); SIGJUMP <= '0'; SIGIMMEDIATE <= '1'; ADA <= "0000"&DAOA2(25 downto 21); NEXT_STATE <= DECODE2; elsif(DAOA2(31 downto 26) = "000100") then --mr(move to register) ADA <= "0000"&DAOA2(25 downto 21); NEXT_STATE <= DECODE2; elsif(DAOA2(31 downto 26) = "000111") then --LED ADA <= "0000"&DAOA2(25 downto 21); NEXT_STATE <= DECODE2; elsif(DAOA2(31 downto 26) = "001000") then --STOP NEXT_STATE <= FIN; else --"000001"=add,"000010"=sub ADA <= "0000"&DAOA2(25 downto 21); ADB <= "0000"&DAOA2(20 downto 16); ALUOP <= DAOA2(31 downto 26); NEXT_STATE <= DECODE2; end if; when DECODE2 => NEXT_STATE <= EX; when EX => ALUINA <= DAOA; SEL3INA <= DAOB; NEXT_STATE <= WB; when WB => ADB <= "111111111"; if(DAOA2(31 downto 26) = "000001" or DAOA2(31 downto 26) = "000010") then WENA <= '1'; DAIA <= ALUOUT; ADA <= "0000"&DAOA2(15 downto 11); elsif(DAOA2(31 downto 26) = "000011") then WENA <= '1'; DAIA <= ALUOUT; ADA <= "0000"&DAOA2(20 downto 16); elsif(DAOA2(31 downto 26) = "000100") then WENA <= '1'; DAIA <= DAOA; ADA <= "0000"&DAOA2(20 downto 16); elsif(DAOA2(31 downto 26) = "000111") then DATAOUTA(7) <= not DAOA(7); DATAOUTA(6) <= not DAOA(6); DATAOUTA(5) <= not DAOA(5); DATAOUTA(4) <= not DAOA(4); DATAOUTA(3) <= not DAOA(3); DATAOUTA(2) <= not DAOA(2); DATAOUTA(1) <= not DAOA(1); DATAOUTA(0) <= not DAOA(0); end if; SIGPCWRITE_EN <= '1'; NEXT_STATE <= FETCHA; when FIN => NEXT_STATE <= FIN; end case; end process; end RTL;