LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; ENTITY shell IS PORT ( rxdat : IN std_logic; xclk : IN std_logic; rxstb : IN std_logic; txstb : IN std_logic; txdat : OUT std_logic; clk : IN std_logic; addr : BUFFER std_logic_vector(15 DOWNTO 0); data : INOUT std_logic_vector(7 DOWNTO 0); rd : BUFFER std_logic; wr : BUFFER std_logic; ramcs : OUT std_logic; sevseg: OUT std_logic_vector(6 DOWNTO 0) ); END shell; ARCHITECTURE one OF shell IS COMPONENT cpu PORT ( clk : IN std_logic; addr : BUFFER std_logic_vector(15 DOWNTO 0); data : INOUT std_logic_vector(7 DOWNTO 0); rd : BUFFER std_logic; wr : BUFFER std_logic; ramcs : OUT std_logic; sevseg: OUT std_logic_vector(6 DOWNTO 0); din : IN std_logic_vector(15 DOWNTO 0); dout : OUT std_logic_vector(7 DOWNTO 0); dsel : IN std_logic_vector(1 DOWNTO 0) ); END COMPONENT; SIGNAL din : std_logic_vector(15 DOWNTO 0); SIGNAL clksel : std_logic_vector(4 DOWNTO 0); SIGNAL dsel : std_logic_vector(1 DOWNTO 0); SIGNAL dout : std_logic_vector(7 DOWNTO 0); SIGNAL txshift : std_logic_vector(7 DOWNTO 0); SIGNAL txshiftnext: std_logic_vector(7 DOWNTO 0); SIGNAL rxshift : std_logic_vector(22 DOWNTO 0); SIGNAL clkdiv : std_logic_vector(23 DOWNTO 0); SIGNAL cpuclk : std_logic; BEGIN u1: cpu PORT MAP ( clk => cpuclk, addr => addr, data => data, rd => rd, wr => wr, ramcs => ramcs, sevseg => sevseg, din => din, dout => dout, dsel => dsel ); -- Drive serial interface WITH txstb SELECT txshiftnext <= txshift(6 DOWNTO 0)&'0' WHEN '0', dout WHEN OTHERS; txrx: PROCESS BEGIN WAIT UNTIL (xclk'event AND xclk='0'); rxshift <= rxshift(21 DOWNTO 0)&(NOT rxdat); txshift <= txshiftnext; END PROCESS txrx; rx: PROCESS BEGIN WAIT UNTIL (rxstb'event AND rxstb='1'); din <= rxshift(15 DOWNTO 0); dsel <= rxshift(17 DOWNTO 16); clksel <= rxshift(22 DOWNTO 18); END PROCESS rx; txdat <= txshift(7); -- Run clock divider PROCESS BEGIN WAIT UNTIL (clk'event AND clk='1'); clkdiv <= clkdiv + 1; END PROCESS; WITH clksel SELECT cpuclk <= clk WHEN "00000", clkdiv(0) WHEN "00001", clkdiv(1) WHEN "00010", clkdiv(2) WHEN "00011", clkdiv(3) WHEN "00100", clkdiv(4) WHEN "00101", clkdiv(5) WHEN "00110", clkdiv(6) WHEN "00111", clkdiv(7) WHEN "01000", clkdiv(8) WHEN "01001", clkdiv(9) WHEN "01010", clkdiv(10) WHEN "01011", clkdiv(11) WHEN "01100", clkdiv(12) WHEN "01101", clkdiv(13) WHEN "01110", clkdiv(14) WHEN "01111", clkdiv(15) WHEN "10000", clkdiv(16) WHEN "10001", clkdiv(17) WHEN "10010", clkdiv(18) WHEN "10011", clkdiv(19) WHEN "10100", clkdiv(20) WHEN "10101", clkdiv(21) WHEN "10110", clkdiv(22) WHEN "10111", clkdiv(23) WHEN "11000", '0' WHEN "11110", '1' WHEN "11111", '0' WHEN OTHERS; END one; ------------------------------------------------------------------- LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; ENTITY cpu IS PORT ( clk : IN std_logic; addr : BUFFER std_logic_vector(15 DOWNTO 0); data : INOUT std_logic_vector(7 DOWNTO 0); rd : BUFFER std_logic; wr : BUFFER std_logic; ramcs : OUT std_logic; sevseg: OUT std_logic_vector(6 DOWNTO 0); din : IN std_logic_vector(15 DOWNTO 0); dout : OUT std_logic_vector(7 DOWNTO 0); dsel : IN std_logic_vector(1 DOWNTO 0) ); END cpu; ARCHITECTURE one OF cpu IS -- Your code goes here COMPONENT alu PORT ( x : IN std_logic_vector(7 DOWNTO 0); y : IN std_logic_vector(7 DOWNTO 0); z : INOUT std_logic_vector(7 DOWNTO 0); cin : IN std_logic; flags : OUT std_logic_vector(3 DOWNTO 0); fn : IN std_logic_vector(3 DOWNTO 0)); END COMPONENT; SIGNAL dataint,aluz:std_logic_vector(7 DOWNTO 0); SIGNAL databus: std_logic_vector(7 DOWNTO 0); SIGNAL a,b,h,l,ir: std_logic_vector(7 DOWNTO 0); SIGNAL pc: std_logic_vector(15 DOWNTO 0); SIGNAL f,flags: std_logic_vector(3 DOWNTO 0); SIGNAL m,oldm,c: std_logic; SIGNAL jumpf: std_logic; SIGNAL reset: std_logic; BEGIN u1: alu PORT MAP ( x => a, y => b, z => aluz, cin => c, flags => flags, fn => ir(6 DOWNTO 3) ); -- Debug interface reset <= din(0); WITH dsel SELECT dout <= ir WHEN "00", a WHEN "01", pc(7 DOWNTO 0) WHEN "10", pc(15 DOWNTO 8) WHEN OTHERS; -- Enable SRAM ramcs <= '0'; -- Seven Segment output PROCESS (reset,wr) BEGIN IF (reset='0') THEN sevseg <= "1100100"; ELSIF wr'event AND wr='1' THEN IF (addr(14)='1') THEN sevseg <= data(6 DOWNTO 0); END IF; END IF; END PROCESS; -- Compute next state of state machine m <= '1' WHEN (ir(7)='1' AND (ir(5 DOWNTO 3)="111" OR ir (2 DOWNTO 0)="001") AND oldm='0') ELSE '0'; -- Latch Registers PROCESS (reset, clk) BEGIN IF (RESET='0') THEN -- Reset case: PC=FFFF, execute NOPs, and guarantee one clock cycle after -- reset returns high, to fetch first instruction from address 0. pc <= "1111111111111111"; ir <= "11111000"; oldm <= '0'; ELSIF clk'event AND clk='1' THEN oldm <= m; IF (m = '0') THEN ir <= databus; END IF; IF (m = '0' OR ir(7 DOWNTO 3) = "11111") THEN pc <= addr+"0000000000000001"; END IF; IF (oldm = '0' AND ir(7) = '1') THEN CASE ir(2 DOWNTO 0) IS WHEN "010" => a <= dataint; WHEN "011" => b <= dataint; WHEN "100" => h <= dataint; WHEN "101" => l <= dataint; WHEN OTHERS => NULL; END CASE; IF (ir(5 DOWNTO 3) /= "111") THEN f <= flags; END IF; END IF; END IF; END PROCESS; -- Control Address Bus PROCESS (ir,m,h,l,pc,f,jumpf) BEGIN IF (ir(7)='0') THEN CASE ir(2 DOWNTO 1) IS WHEN "00" => jumpf <= ir(0); WHEN "01" => jumpf <= f(1) XOR ir(0); WHEN "10" => jumpf <= f(2) XOR ir(0); WHEN OTHERS => jumpf <= f(3) XOR ir(0); END CASE; IF (jumpf='1') THEN addr <= h & l; ELSE addr <= pc; END IF; ELSE IF (m='1' AND (ir(6 DOWNTO 3)="0111" OR ir(2 DOWNTO 0)="001")) THEN addr <= h & l; ELSE addr <= pc; END IF; END IF; END PROCESS; -- Control Data Bus, External Data Bus, RD and WR lines PROCESS(ir,m,clk,dataint,databus,data) BEGIN IF (ir(7)='1' AND ir(5 DOWNTO 3)/="111" AND ir(2 DOWNTO 0)="001" AND m='1') THEN databus <= dataint; data <= databus; rd <= '1'; wr <= clk; ELSE databus <= data; data <= "ZZZZZZZZ"; rd <= clk; wr <= '1'; END IF; END PROCESS; -- Control Internal Data Bus dataint <= databus WHEN (ir(7)='1' AND ir(5 DOWNTO 3)="111" AND m='1') ELSE aluz; -- Control ALU WITH ir(4 DOWNTO 3) SELECT c <= '0' WHEN "00", '1' WHEN "10", f(2) WHEN OTHERS; END one; --------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.all; ENTITY alu IS PORT ( x : IN std_logic_vector(7 DOWNTO 0); y : IN std_logic_vector(7 DOWNTO 0); z : INOUT std_logic_vector(7 DOWNTO 0); cin : IN std_logic; flags : OUT std_logic_vector(3 DOWNTO 0); fn : IN std_logic_vector(3 DOWNTO 0) ); END alu; ARCHITECTURE one OF alu IS COMPONENT aluslice PORT ( x,y : IN std_logic; z : OUT std_logic; cin : IN std_logic; cout : OUT std_logic; fn : IN std_logic_vector(3 DOWNTO 0)); END COMPONENT; SIGNAL c: std_logic_vector(8 DOWNTO 0); BEGIN g1: FOR i IN 0 TO 7 GENERATE comp: aluslice PORT MAP ( x => x(i), y => y(i), z => z(i), cin => c(i), cout => c(i+1), fn => fn ); END GENERATE g1; c(0) <= cin; flags(0) <= '0'; flags(1) <= '1' WHEN z="00000000" ELSE '0'; flags(2) <= z(7); flags(3) <= c(8); END one; --------------------------------------------------------------------- LIBRARY IEEE; USE ieee.std_logic_1164.all; ENTITY aluslice IS PORT ( x : IN std_logic; y : IN std_logic; z : OUT std_logic; cin : IN std_logic; cout : OUT std_logic; fn : IN std_logic_vector(3 DOWNTO 0) ); END aluslice; ARCHITECTURE one OF aluslice IS SIGNAL yin : std_logic; SIGNAL halfa : std_logic; SIGNAL halfx : std_logic; SIGNAL fullx : std_logic; BEGIN yin <= (y OR fn(3)) XOR (fn(1) AND NOT fn(2)); halfa <= x AND yin; halfx <= x XOR yin; cout <= halfa OR (cin AND halfx); fullx <= cin XOR halfx; WITH fn(2 DOWNTO 0) SELECT z <= fullx WHEN "000", fullx WHEN "001", fullx WHEN "010", fullx WHEN "011", halfa WHEN "100", x OR yin WHEN "101", halfx WHEN "110", '-' WHEN OTHERS; END one;