发信人: bobby (五系一家亲), 信区: ECE
标  题: 简单的VHDL写的CPU模型
发信站: 哈工大紫丁香 (2002年04月04日14:17:11 星期四), 站内信件

发信人: dongyun (冬云), 信区: Electronics
标  题: 用VHDL写的CPU模型(极简单)
发信站: 哈工大紫丁香 (2001年05月23日21:43:34 星期三), 站内信件

发信人: realwhz (jesse), 信区: METech
标  题: 用VHDL写的CPU模型(极简单)
发信站: BBS 水木清华站 (Sat May 19 19:27:52 2001)


library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity program_counter is
    port (
        clk, en_A, ld, inc, reset: in STD_LOGIC;
        aBus: out STD_LOGIC_VECTOR(15 downto 0);
        dBus: in STD_LOGIC_VECTOR(15 downto 0)
    );
end program_counter;
architecture pcArch of program_counter is
signal pcReg: STD_LOGIC_VECTOR(15 downto 0);
begin
  process(clk) begin
   if clk'event and clk = '1' then
    if reset = '1' then
     pcReg <= "0000000000000000";
    elsif ld = '1' then
     pcReg <= dBus;
     pcReg <= dBus;
    elsif inc = '1' then
     pcReg <= pcReg + "0000000000000001";
    end if;
   end if;
  end process;
  aBus <= pcReg when en_A = '1' else "ZZZZZZZZZZZZZZZZ";
end pcArch;
---------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
entity instruction_register is
    port (
        clk, en_A, en_D, ld, reset: in STD_LOGIC;
        aBus: out STD_LOGIC_VECTOR(15 downto 0);
        dBus: inout STD_LOGIC_VECTOR(15 downto 0);
        load, store, add, neg, halt, branch: out STD_LOGIC;
        cbranch, iload, istore, dload, dadd: out STD_LOGIC
    );
end instruction_register;
architecture irArch of instruction_register is
signal irReg: STD_LOGIC_VECTOR(15 downto 0);
begin
begin
  process(clk) begin
   if clk'event and clk = '0' then -- load on falling edge
    if reset = '1' then
     irReg <= "0000000000000000";
    elsif ld = '1' then
     irReg <= dBus;
    end if;
   end if;
  end process;
  aBus <= "0000" & irReg(11 downto 0) when en_A = '1' else
     "ZZZZZZZZZZZZZZZZ";
  dBus <= "0000" & irReg(11 downto 0) when en_D = '1' else
     "ZZZZZZZZZZZZZZZZ";
  load    <= '1' when irReg(15 downto 12) = "0000"  else '0';
  store   <= '1' when irReg(15 downto 12) = "0001"  else '0';
  add     <= '1' when irReg(15 downto 12) = "0010"  else '0';
  neg     <= '1' when irReg = "0011" & "000000000000"  else '0';
  halt    <= '1' when irReg = "0011" & "000000000001"  else '0';
  branch  <= '1' when irReg(15 downto 12) = "0100"  else '0';
  cbranch <= '1' when irReg(15 downto 12) = "0101"  else '0';
  iload   <= '1' when irReg(15 downto 12) = "0110"  else '0';
  istore  <= '1' when irReg(15 downto 12) = "0111"  else '0';
  istore  <= '1' when irReg(15 downto 12) = "0111"  else '0';
  dload   <= '1' when irReg(15 downto 12) = "1000"  else '0';
  dadd    <= '1' when irReg(15 downto 12) = "1001"  else '0';
end irArch;
---------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
entity indirect_addr_register is
    port (
        clk, en_A, ld, reset: in STD_LOGIC;
        aBus: out STD_LOGIC_VECTOR(15 downto 0);
        dBus:  in STD_LOGIC_VECTOR(15 downto 0)
    );
end indirect_addr_register;
architecture iarArch of indirect_addr_register is
signal iarReg: STD_LOGIC_VECTOR(15 downto 0);
begin
  process(clk) begin
   if clk'event and clk = '1' then
    if reset = '1' then
     iarReg <= "0000000000000000";
    elsif ld = '1' then
     iarReg <= dBus;
     iarReg <= dBus;
    end if;
   end if;
  end process;
  aBus <= iarReg when en_A = '1' else
     "ZZZZZZZZZZZZZZZZ";
end iarArch;
---------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity accumulator is
    port (
        clk, en_D, ld, selAlu, reset: in STD_LOGIC;
        aluD: in STD_LOGIC_VECTOR(15 downto 0);
        dBus: inout STD_LOGIC_VECTOR(15 downto 0);
        q: out STD_LOGIC_VECTOR(15 downto 0)
    );
end accumulator;
architecture accArch of accumulator is
signal accReg: STD_LOGIC_VECTOR(15 downto 0);
begin
  process(clk) begin
  process(clk) begin
   if clk'event and clk = '1' then
    if reset = '1' then
     accReg <= "0000000000000000";
    elsif ld = '1' and selAlu = '1' then
     accReg <= aluD;
    elsif ld = '1' and selAlu = '0' then
     accReg <= dBus;
    end if;
   end if;
  end process;
  dBus <= accReg when en_D = '1' else
     "ZZZZZZZZZZZZZZZZ";
  q <= accReg;
end accArch;
---------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity alu is
    port (
        op: in STD_LOGIC_VECTOR(1 downto 0);
        accD: in STD_LOGIC_VECTOR(15 downto 0);
        accD: in STD_LOGIC_VECTOR(15 downto 0);
        dBus: in STD_LOGIC_VECTOR(15 downto 0);
        result: out STD_LOGIC_VECTOR(15 downto 0);
        accZ: out STD_LOGIC
    );
end alu;
architecture aluArch of alu is
begin
  result <= (not accD) + "0000000000000001" when op ="00" else
       accD + dBus when op ="01" else
       "0000000000000000";
  accZ <= not (accD(0) or  accD(1) or  accD(2) or  accD(3) or
          accD(4) or  accD(5) or  accD(6) or  accD(7) or
          accD(8) or  accD(9) or accD(10) or accD(11) or
         accD(12) or accD(13) or accD(14) or accD(15)
     );
end aluArch;
---------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
entity ram is
    port (
    port (
        r_w, en, reset: in STD_LOGIC;
        aBus: in STD_LOGIC_VECTOR(15 downto 0);
        dBus: inout STD_LOGIC_VECTOR(15 downto 0)
    );
end ram;
architecture ramArch of ram is
type ram_typ is array(0 to 63) of STD_LOGIC_VECTOR(15 downto 0);
signal ram: ram_typ;
begin
  process(en, reset, r_w, aBus, dBus) begin
   if reset = '1' then
    ram(0) <= x"0014";
    ram(1) <= x"3000";
    ram(2) <= x"2005";
    ram(3) <= x"1015";
    ram(4) <= x"4006";
    ram(5) <= x"3001";
    ram(6) <= x"5005";
    ram(7) <= x"0016";
    ram(8) <= x"500a";
    ram(9) <= x"3001";
    ram(10) <= x"6017";
    ram(10) <= x"6017";
    ram(11) <= x"7018";
    ram(12) <= x"8022";
    ram(13) <= x"913f";
    ram(14) <= x"3001";
    ram(20) <= x"5555";
    ram(22) <= x"0000";
    ram(23) <= x"0004";
    ram(24) <= x"0005";
   elsif r_w = '0' then
    ram(conv_integer(unsigned(aBus))) <= dBus;
   end if;
  end process;
  dBus <= ram(conv_integer(unsigned(aBus)))
    when reset = '0' and en = '1' and r_w = '1' else
   "ZZZZZZZZZZZZZZZZ";
end ramArch;
---------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
entity controller is
    port (
     clk, reset:   in  STD_LOGIC;
     clk, reset:   in  STD_LOGIC;
     mem_enD, mem_rw:   out STD_LOGIC;
     pc_enA, pc_ld, pc_inc:   out STD_LOGIC;
     ir_enA, ir_enD, ir_ld:   out STD_LOGIC;
     ir_load, ir_store, ir_add: in  STD_LOGIC;
 ir_neg, ir_halt, ir_branch:  in  STD_LOGIC;
        ir_cbranch, ir_iload:  in  STD_LOGIC;
        ir_istore, ir_dload, ir_dadd: in  STD_LOGIC;
     iar_enA, iar_ld:   out STD_LOGIC;
     acc_enD, acc_ld, acc_selAlu:  out STD_LOGIC;
     alu_accZ:    in  STD_LOGIC;
     alu_op:    out STD_LOGIC_VECTOR(1 downto 0)
    );
end controller;
architecture controllerArch of controller is
type state_type is ( reset_state,
   fetch0, fetch1,
   load0, load1,
   store0, store1,
   add0, add1,
   negate0, negate1,
   halt,
   branch0, branch1,
   branch0, branch1,
   cbranch0, cbranch1,
   iload0, iload1, iload2, iload3,
   istore0, istore1, istore2, istore3,
   dload0, dload1,
   dadd0, dadd1
   );
signal state: state_type;
begin
  process(clk) begin
   if clk'event and clk = '1' then
    if reset = '1' then state <= reset_state;
      else
       case state is
       when reset_state => state <= fetch0;
       when fetch0 => state <= fetch1;
     when fetch1 =>
      if ir_load = '1' then state <= load0;
      elsif ir_store   = '1' then state <= store0;
      elsif ir_add     = '1' then state <= add0;
      elsif ir_neg     = '1' then state <= negate0;
      elsif ir_halt    = '1' then state <= halt;
      elsif ir_branch  = '1' then state <= branch0;
      elsif ir_branch  = '1' then state <= branch0;
      elsif ir_cbranch = '1' then state <= cbranch0;
      elsif ir_iload   = '1' then state <= iload0;
      elsif ir_istore  = '1' then state <= istore0;
      elsif ir_dload   = '1' then state <= dload0;
      elsif ir_dadd    = '1' then state <= dadd0;
      end if;
     when load0 =>  state <= load1;
     when load1 =>  state <= fetch0;
   when store0 =>  state <= store1;
     when store1 => state <= fetch0;
     when add0 =>  state <= add1;
     when add1 =>  state <= fetch0;
     when negate0 => state <= negate1;
     when negate1 => state <= fetch0;
     when halt =>  state <= halt;
     when branch0 => state <= branch1;
     when branch1 => state <= fetch0;
     when cbranch0 => state <= cbranch1;
     when cbranch1 => state <= fetch0;
     when iload0 =>  state <= iload1;
     when iload1 =>  state <= iload2;
     when iload2 =>  state <= iload3;
      elsif ir_branch  = '1' then state <= branch0;
      elsif ir_cbranch = '1' then state <= cbranch0;
      elsif ir_iload   = '1' then state <= iload0;
      elsif ir_istore  = '1' then state <= istore0;
      elsif ir_dload   = '1' then state <= dload0;
      elsif ir_dadd    = '1' then state <= dadd0;
      end if;
     when load0 =>  state <= load1;
     when load1 =>  state <= fetch0;
   when store0 =>  state <= store1;
     when store1 => state <= fetch0;
     when add0 =>  state <= add1;
     when add1 =>  state <= fetch0;
     when negate0 => state <= negate1;
     when negate1 => state <= fetch0;
     when halt =>  state <= halt;
     when branch0 => state <= branch1;
     when branch1 => state <= fetch0;
     when cbranch0 => state <= cbranch1;
     when cbranch1 => state <= fetch0;
     when iload0 =>  state <= iload1;
     when iload1 =>  state <= iload2;
     when iload2 =>  state <= iload3;
     when iload2 =>  state <= iload3;
     when iload3 =>  state <= fetch0;
     when istore0 => state <= istore1;
     when istore1 => state <= istore2;
     when istore2 => state <= istore3;
     when istore3 => state <= fetch0;
     when dload0 =>  state <= dload1;
     when dload1 =>  state <= fetch0;
     when dadd0 =>  state <= dadd1;
     when dadd1 =>  state <= fetch0;
     when others =>  state <= halt;
     end case;
    end if;
   end if;
  end process;
  process(clk) begin -- special process for memory write timing
   if clk'event and clk = '0' then
    if state = store0 or state = istore2 then
     mem_rw <= '0';
    else
     mem_rw <= '1';
    end if;
   end if;
   end if;
  end process;
  mem_enD <= '1'   when state =  fetch0 or state =  fetch1 or
     state =   load0 or state =   load1 or
     state =    add0 or state =    add1 or
     state =  iload0 or state =  iload1 or
     state =  iload2 or state =  iload3 or
     state = istore0 or state = istore1
       else '0';
  pc_enA <= '1'    when state =  fetch0 or state = fetch1
       else '0';
  pc_ld <= '1'    when state = branch0 or (state = cbranch0 and alu_accZ
 = '
1')
       else '0';
  pc_inc <= '1'    when state = fetch1
       else '0';
  ir_enA <= '1'    when state = load0 or state = load1 or
     state = store0 or state =  store1 or
     state =  add0 or state =  add1 or
     state = iload0 or state = iload1 or
     state = istore0 or state = istore1
       else '0';
  ir_enD <= '1'    when state = branch0 or state = cbranch0 or state =
dload
       else "00";
end controllerArch;
---------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
entity top_level is
    port (
        clk, reset:   in  STD_LOGIC;
        abusX:     out STD_LOGIC_VECTOR(15 downto 0);
        dbusX:     out STD_LOGIC_VECTOR(15 downto 0);
        mem_enDX, mem_rwX:   out STD_LOGIC;
        pc_enAX, pc_ldX, pc_incX: out STD_LOGIC;
        ir_enAX, ir_enDX, ir_ldX: out STD_LOGIC;
        iar_enAX, iar_ldX:  out STD_LOGIC;
        acc_enDX, acc_ldX, acc_selAluX: out STD_LOGIC;
        acc_QX:    out STD_LOGIC_VECTOR(15 downto 0);
        alu_accZX:   out STD_LOGIC;
        alu_opX:   out STD_LOGIC_VECTOR(1 downto 0)
    );
end top_level;
architecture topArch of top_level is
component program_counter
    port (
    port (
        clk, en_A, ld, inc, reset: in STD_LOGIC;
        aBus: out STD_LOGIC_VECTOR(15 downto 0);
        dBus: in STD_LOGIC_VECTOR(15 downto 0)
    );
end component;
component instruction_register
    port (
        clk, en_A, en_D, ld, reset: in STD_LOGIC;
        aBus: out STD_LOGIC_VECTOR(15 downto 0);
        dBus: inout STD_LOGIC_VECTOR(15 downto 0);
        load, store, add, neg, halt, branch: out STD_LOGIC;
        cbranch, iload, istore, dload, dadd: out STD_LOGIC
    );
end component;
component indirect_addr_register
    port (
        clk, en_A, ld, reset: in STD_LOGIC;
        aBus: out STD_LOGIC_VECTOR(15 downto 0);
        dBus:  in STD_LOGIC_VECTOR(15 downto 0)
    );
end component;
component accumulator
component accumulator
    port (
        clk, en_D, ld, selAlu, reset: in STD_LOGIC;
        aluD: in STD_LOGIC_VECTOR(15 downto 0);
        dBus: inout STD_LOGIC_VECTOR(15 downto 0);
        q: out STD_LOGIC_VECTOR(15 downto 0)
    );
end component;
component alu
    port (
        op: in STD_LOGIC_VECTOR(1 downto 0);
        accD: in STD_LOGIC_VECTOR(15 downto 0);
        dBus: in STD_LOGIC_VECTOR(15 downto 0);
        result: out STD_LOGIC_VECTOR(15 downto 0);
        accZ: out STD_LOGIC
    );
end component;
component ram
    port (
        r_w, en, reset: in STD_LOGIC;
        aBus: in STD_LOGIC_VECTOR(15 downto 0);
        dBus: inout STD_LOGIC_VECTOR(15 downto 0)
    );
    );
end component;
component controller
    port (
     clk, reset:   in  STD_LOGIC;
     mem_enD, mem_rw:   out STD_LOGIC;
     pc_enA, pc_ld, pc_inc:   out STD_LOGIC;
     ir_enA, ir_enD, ir_ld:   out STD_LOGIC;
     ir_load, ir_store, ir_add: in  STD_LOGIC;
 ir_neg, ir_halt, ir_branch:  in  STD_LOGIC;
        ir_cbranch, ir_iload:  in  STD_LOGIC;
        ir_istore, ir_dload, ir_dadd: in  STD_LOGIC;
     iar_enA, iar_ld:   out STD_LOGIC;
     acc_enD, acc_ld, acc_selAlu:  out STD_LOGIC;
     alu_accZ:    in  STD_LOGIC;
     alu_op:    out STD_LOGIC_VECTOR(1 downto 0)
    );
end component;
signal abus:     STD_LOGIC_VECTOR(15 downto 0);
signal dbus:     STD_LOGIC_VECTOR(15 downto 0);
signal mem_enD, mem_rw:   STD_LOGIC;
signal pc_enA, pc_ld, pc_inc:  STD_LOGIC;
signal ir_enA, ir_enD, ir_ld:  STD_LOGIC;
signal ir_enA, ir_enD, ir_ld:  STD_LOGIC;
signal ir_load, ir_store, ir_add: STD_LOGIC;
signal ir_negate, ir_halt, ir_branch: STD_LOGIC;
signal ir_cbranch, ir_iload, ir_istore:STD_LOGIC;
signal ir_dload, ir_dadd:  STD_LOGIC;
signal iar_enA, iar_ld:  STD_LOGIC;
signal acc_enD, acc_ld, acc_selAlu: STD_LOGIC;
signal acc_Q:    STD_LOGIC_VECTOR(15 downto 0);
signal alu_op:    STD_LOGIC_VECTOR(1 downto 0);
signal alu_accZ:   STD_LOGIC;
signal alu_result:   STD_LOGIC_VECTOR(15 downto 0);
begin
  pc: program_counter port map(clk, pc_enA, pc_ld, pc_inc, reset, abus,
 dbus
);
  ir: instruction_register port map(clk, ir_enA, ir_enD, ir_ld, reset,
abus,
 dbus,
        ir_load, ir_store, ir_add,
        ir_negate, ir_halt, ir_branch,
        ir_cbranch, ir_iload, ir_istore,
        ir_dload, ir_dadd);
  iar: indirect_addr_register port map(clk, iar_enA, iar_ld, reset,
abus, db
us);
  acc: accumulator port map(clk, acc_enD, acc_ld, acc_selAlu, reset,
alu_res
  acc: accumulator port map(clk, acc_enD, acc_ld, acc_selAlu, reset,
alu_res
ult, dbus, acc_Q);
  aluu: alu port map(alu_op, acc_Q, dbus, alu_result, alu_accZ);
  mem: ram port map(mem_rw, mem_enD, reset, abus, dbus);
  ctl: controller port map(clk, reset, mem_enD, mem_rw, pc_enA, pc_ld,
pc_in
c,
      ir_enA, ir_enD, ir_ld, ir_load, ir_store, ir_add,
      ir_negate, ir_halt, ir_branch, ir_cbranch, ir_iload,
      ir_istore, ir_dload, ir_dadd,
      iar_enA, iar_ld, acc_enD, acc_ld, acc_selAlu,
      alu_accZ, alu_op);
   abusX <= abus;
   dbusX <= dbus;
   mem_enDX <= mem_enD;
   mem_rwX <= mem_rw;
   pc_enAX <= pc_enA;
   pc_ldX <= pc_ld;
   pc_incX <= pc_inc;
   ir_enAX <= ir_enA;
   ir_enDX <= ir_enD;
   ir_ldX <= ir_ld;
   iar_enAX <= iar_enA;
   iar_ldX <= iar_ld;
   abusX <= abus;
   acc_enDX <= acc_enD;
   acc_ldX <= acc_ld;
   acc_selAluX <= acc_selAlu;
   acc_QX <= acc_Q;
   alu_opX <= alu_op;
   alu_accZX <= alu_accZ;
end topArch;
--
※ 来源:·BBS 水木清华站 smth.org·[FROM: 202.100.58.88]

--
※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: CGzong.hit.edu.cn]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:205.183毫秒