?? cpu.vhd
字號:
package commonConstants is constant wordSize: integer := 32; constant adrLength: integer := 16;end package commonConstants;library IEEE;use IEEE.std_logic_1164.all;use IEEE.std_logic_arith.all;use work.commonConstants.all;entity ram is port ( reset, en, r_w: in STD_LOGIC; aBus: in STD_LOGIC_VECTOR(adrLength-1 downto 0); dBus: inout STD_LOGIC_VECTOR(wordSize-1 downto 0));end ram;architecture ramArch of ram isconstant resAdrLength: integer := 6; -- address length restricted within architectureconstant memSize: integer := 2**resAdrLength;type ram_typ is array(0 to memSize-1) of STD_LOGIC_VECTOR(wordSize-1 downto 0);signal ram: ram_typ;begin process(reset, en, r_w, aBus, dBus) begin if reset = '1' then -- basic instruction check ram(0) <= x"00002005"; -- direct load ram(1) <= x"00000001"; -- negate ram(2) <= x"00004004"; -- direct store ram(3) <= x"00000000"; -- halt ram(5) <= x"4009999A"; -- X = 4009999A(01000000000010011001100110011010) elsif en = '1' and r_w = '0' then ram(conv_integer(unsigned(aBus(resAdrLength-1 downto 0)))) <= dBus; end if; end process; dBus <= ram(conv_integer(unsigned(aBus(resAdrLength-1 downto 0)))) when reset = '0' and en = '1' and r_w = '1' else (dbus'range => 'Z');end ramArch;---------------------------------------------------------library IEEE;use IEEE.std_logic_1164.all;use IEEE.std_logic_arith.all;use IEEE.std_logic_unsigned.all;use work.commonConstants.all;entity cpu is port ( clk, reset : in std_logic; m_en, m_rw : out std_logic; aBus : out std_logic_vector(adrLength-1 downto 0); dBus : inout std_logic_vector(wordSize-1 downto 0); -- these signals "exported" so they can be monitored in post-P&R simulation pcX, iarX : out std_logic_vector(adrLength-1 downto 0); iregX, accX, aluX : out std_logic_vector(wordSize-1 downto 0));end cpu;architecture cpuArch of cpu istype state_type is ( reset_state, fetch, halt, negate, mload, dload, iload, dstore, istore, branch, brZero, brPos, brNeg, add);signal state: state_type;type tick_type is (t0, t1, t2, t3, t4, t5, t6, t7);signal tick: tick_type;signal pc: std_logic_vector(adrLength-1 downto 0); -- program countersignal iReg: std_logic_vector(wordSize-1 downto 0); -- instruction registersignal iar: std_logic_vector(adrLength-1 downto 0); -- indirect address registersignal acc: std_logic_vector(wordSize-1 downto 0); -- accumulatorsignal alu: std_logic_vector(wordSize-1 downto 0); -- alu outputbegin alu <= (not acc) + x"00000001" when state = negate else acc + dbus when state = add else (alu'range => '0'); pcX <= pc; iregX <= ireg; iarX <= iar; accX <= acc; aluX <= alu; process(clk) -- perform actions that occur on rising clock edges function nextTick(tick: tick_type) return tick_type is begin -- return next logical value for tick case tick is when t0 => return t1; when t1 => return t2; when t2 => return t3; when t3 => return t4; when t4 => return t5; when t5 => return t6; when t6 => return t7; when others => return t0; end case; end function nextTick; procedure decode is begin -- Instruction decoding. case iReg(15 downto 12) is when x"0" => if iReg(11 downto 0) = x"000" then state <= halt; elsif iReg(11 downto 0) = x"001" then state <= negate; end if; when x"1" => state <= mload; when x"2" => state <= dload; when x"3" => state <= iload; when x"4" => state <= dstore; when x"5" => state <= istore; when x"6" => state <= branch; when x"7" => state <= brZero; when x"8" => state <= brPos; when x"9" => state <= brNeg; when x"a" => state <= add; when others => state <= halt; end case; end procedure decode; procedure wrapup is begin -- Do this at end of every instruction state <= fetch; tick <= t0; end procedure wrapup; begin if clk'event and clk = '1' then if reset = '1' then state <= reset_state; tick <= t0; pc <= (pc'range => '0'); iReg <= (iReg'range => '0'); acc <= (acc'range => '0'); iar <= (iar'range => '0'); else tick <= nextTick(tick) ; -- advance time by default case state is when reset_state => state <= fetch; tick <= t0; when fetch => if tick = t1 then iReg <= dBus; end if; if tick = t2 then decode; pc <= pc + '1'; tick <= t0; end if; when halt => tick <= t0; -- do nothing when negate => acc <= alu; wrapup; -- load instructions when mload => if iReg(11) = '0' then -- sign extension acc <= x"00000" & ireg(11 downto 0); else acc <= x"0000f" & ireg(11 downto 0); end if; wrapup; when dload => if tick = t1 then acc <= dBus; end if; if tick = t2 then wrapup; end if; when iload => if tick = t1 then iar <= dBus(15 downto 0); end if; --some problems if tick = t4 then acc <= dBus; end if; if tick = t5 then wrapup; end if; -- store instructions when dstore => if tick = t4 then wrapup; end if; when istore => if tick = t1 then iar <= dBus(15 downto 0); end if; --some problems if tick = t7 then wrapup; end if; -- branch instructions when branch => pc <= x"0" & iReg(11 downto 0); wrapup; when brZero => if acc = x"0000" then pc <= x"0" & iReg(11 downto 0); end if; wrapup; when brPos => if acc(15) = '0' and acc /= x"0000" then pc <= x"0" & iReg(11 downto 0); end if; wrapup; when brNeg => if acc(15) = '1' then pc <= x"0" & iReg(11 downto 0); end if; wrapup; -- arithmetic instructions when add => if tick = t1 then acc <= alu; end if; if tick = t2 then wrapup; end if; when others => state <= halt; end case; end if; end if; end process; process(clk) begin -- perform actions that occur on falling clock edges if clk'event and clk ='0' then if reset = '1' then m_en <= '0'; m_rw <= '1'; aBus <= (aBus'range => '0'); dBus <= (dBus'range => 'Z'); else case state is when fetch => if tick = t0 then m_en <= '1'; aBus <= pc; end if; if tick = t2 then m_en <= '0'; aBus <= (aBus'range => '0'); end if; when dload => if tick = t0 then m_en <= '1'; aBus <= x"0" & iReg(11 downto 0); end if; if tick = t2 then m_en <= '0'; aBus <= (aBus'range => '0'); end if; when iload => if tick = t0 then m_en <= '1'; aBus <= x"0" & iReg(11 downto 0); end if; if tick = t2 then m_en <= '0'; aBus <= (aBus'range => '0'); end if; if tick = t3 then m_en <= '1'; aBus <= iar; end if; if tick = t5 then m_en <= '0'; aBus <= (abus'range => '0'); end if; when dstore => if tick = t0 then m_en <= '1'; aBus <= x"0" & iReg(11 downto 0); end if; if tick = t1 then m_rw <= '0'; dBus <= acc; end if; if tick = t3 then m_rw <= '1'; end if; if tick = t4 then m_en <= '0'; aBus <= (abus'range => '0'); dBus <= (dBus'range => 'Z'); end if; when istore => if tick = t0 then m_en <= '1'; aBus <= x"0" & iReg(11 downto 0); end if; if tick = t2 then m_en <= '0'; aBus <= (aBus'range => '0'); end if; if tick = t3 then m_en <= '1'; aBus <= iar; end if; if tick = t4 then m_rw <= '0'; dBus <= acc; end if; if tick = t6 then m_rw <= '1'; end if; if tick = t7 then m_en <= '0'; aBus <= (abus'range => '0'); dBus <= (dBus'range => 'Z'); end if; when add => if tick = t0 then m_en <= '1'; aBus <= x"0" & iReg(11 downto 0); end if; if tick = t2 then m_en <= '0'; aBus <= (aBus'range => '0'); end if; when others => -- do nothing end case; end if; end if; end process;end cpuArch;-------------------------------library IEEE;use IEEE.std_logic_1164.all;use IEEE.std_logic_arith.all;use work.commonConstants.all;entity top is port( clk, reset: in STD_LOGIC; mem_enX, mem_rwX : out std_logic; aBusX : out std_logic_vector(adrLength-1 downto 0); dBusX : out std_logic_vector(wordSize-1 downto 0); pcX, iarX : out std_logic_vector(adrLength-1 downto 0); iregX, accX, aluX : out std_logic_vector(wordSize-1 downto 0));end top;architecture topArch of top iscomponent ram port ( reset, en, r_w: in STD_LOGIC; aBus: in STD_LOGIC_VECTOR(adrLength-1 downto 0); dBus: inout STD_LOGIC_VECTOR(wordSize-1 downto 0));end component;component cpu port ( clk, reset: in STD_LOGIC; m_en, m_rw: out STD_LOGIC; aBus: out STD_LOGIC_VECTOR(adrLength-1 downto 0); dBus: inout STD_LOGIC_VECTOR(wordSize-1 downto 0); pcX, iarX : out std_logic_vector(adrLength-1 downto 0); iregX, accX, aluX : out std_logic_vector(wordSize-1 downto 0));end component;signal mem_en, mem_rw: STD_LOGIC;signal aBus, pc, iar: STD_LOGIC_VECTOR(adrLength-1 downto 0);signal dBus, ireg, acc, alu: std_logic_vector(wordSize-1 downto 0);begin ramC: ram port map(reset, mem_en, mem_rw, aBus, dBus); cpuC: cpu port map(clk, reset, mem_en, mem_rw, aBus, dBus, pc, iar, ireg, acc, alu); mem_enX <= mem_en; mem_rwX <= mem_rw; aBusX <= aBus; dBusX <= dBus; pcX <= pc; iregX <= ireg; iarX <= iar; accX <= acc; aluX <= alu;end topArch;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -