- ----------------------------------------------------------------------------- - -- - -- - -- Author: Peter Thole - -- University of Tuebingen - -- Wilhelm-Schickard-Institut for Computer Science - -- - -- - -- VHDL-Description of a simple processor with five instructions - -- - ----------------------------------------------------------------------------- ENTITY rech IS port ( clk: in bit; -- the clock reset: in bit; -- synchronous reset dw : out bit_vector(7 downto 0); carry_out : out bit; dr : in bit_vector(7 downto 0); RAMRD : out bit; adr : out bit_vector(15 downto 0); opc : out bit_vector(3 downto 0)); END rech; ARCHITECTURE fsm OF rech IS BEGIN -- fsm -- Comment: The process contains two procedure calls, which -- implementation depents on the synthesis system. -- -- i) step(clk,reset) means WAIT UNTIL clk'EVENT AND clk='1'; -- EXIT outest_loop WHEN reset = '1'; -- -- ii) plus(a,b,carry,s) is an addition of the bitvectors a,b -- to sum s, carry is the carry flag, the length of a,b and s -- is eight bit s : PROCESS -- the instructions CONSTANT LDA : bit_vector(3 downto 0) := "0000"; CONSTANT STA : bit_vector(3 downto 0) := "0010"; CONSTANT ADD : bit_vector(3 downto 0) := "0101"; CONSTANT Nnor : bit_vector(3 downto 0) := "0100"; CONSTANT JNC : bit_vector(3 downto 0) := "0011"; -- local variables VARIABLE accu, adress_unit : bit_vector(7 downto 0); VARIABLE op_code : bit_vector(3 downto 0); VARIABLE pc : bit_vector(15 downto 0); VARIABLE carry : bit; BEGIN -- PROCESS s -- Initializing of variables and output signals dw <= "00000000"; carry_out <= '0'; RAMRD <= '1'; adr <= "0000000000000000"; opc <= "0000"; op_code := "0000"; accu := "00000000"; pc := "0000000000000000"; adress_unit := "00000000"; carry := '0'; -- global loop: step(clk,reset); IF (reset='1') THEN ELSE outest_loop: LOOP op_code := dr(3 downto 0); -- load opcode opc <= op_code; pc := pc + 1; adr <= pc; step(clk,reset); pc := pc + 1; adr <= pc; CASE op_code IS WHEN LDA => accu := dr; -- load accu dw <= accu; WHEN STA => adress_unit := dr; -- load low byte of adress step(clk,reset); adr <= dr & adress_unit;-- load high byte of adress RAMRD <= '0'; -- store accu dw <= accu; step(clk,reset); RAMRD <= '1'; pc := pc + 1; adr <= pc; WHEN NnOR => adress_unit := dr; step(clk,reset); adr <= dr & adress_unit; step(clk,reset); accu := accu NOR dr; dw <= accu; pc := pc + 1; adr <= pc; WHEN ADD => adress_unit := dr; step(clk,reset); adr <= dr & adress_unit; step(1); plus(accu,dr,carry,accu); carry_out <= carry; dw <= accu; pc := pc + 1; adr <= pc; WHEN JNC => IF (carry = '1') THEN step(clk,reset); pc := pc + 1; adr <= pc; ELSE adress_unit := dr; step(clk,reset); pc(15 downto 8) := dr; pc(7 downto 0) := adress_unit; adr <= pc; END IF; WHEN others => END CASE; -- step(clk,reset); -- end of global loop END LOOP outest_loop; END IF; END PROCESS s; END fsm;