kirill_76rus

Untitled

Dec 2nd, 2020
732
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- mips.vhd
  2. -- From Section 7.6 of Digital Design & Computer Architecture
  3. -- Updated to VHDL 2008 26 July 2011 David_Harris@hmc.edu
  4.  
  5. library IEEE;
  6. use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD_UNSIGNED.all;
  7.  
  8. entity testbench is
  9. end;
  10.  
  11. architecture test of testbench is
  12.   component top
  13.     port(clk, reset:           in  STD_LOGIC;
  14.          writedata, dataadr:   out STD_LOGIC_VECTOR(31 downto 0);
  15.          memwrite:             out STD_LOGIC);
  16.   end component;
  17.   signal writedata, dataadr:    STD_LOGIC_VECTOR(31 downto 0);
  18.   signal clk, reset,  memwrite: STD_LOGIC;
  19. begin
  20.  
  21.   -- instantiate device to be tested
  22.   dut: top port map(clk, reset, writedata, dataadr, memwrite);
  23.  
  24.   -- Generate clock with 10 ns period
  25.   process begin
  26.     clk <= '1';
  27.     wait for 5 ns;
  28.     clk <= '0';
  29.     wait for 5 ns;
  30.   end process;
  31.  
  32.   -- Generate reset for first two clock cycles
  33.   process begin
  34.     reset <= '1';
  35.     wait for 22 ns;
  36.     reset <= '0';
  37.     wait;
  38.   end process;
  39.  
  40.   -- check that 7 gets written to address 84 at end of program
  41.   process (clk) begin
  42.     if (clk'event and clk = '0' and memwrite = '1') then
  43.       if (to_integer(dataadr) = 84 and to_integer(writedata) = 7) then
  44.         report "NO ERRORS: Simulation succeeded" severity failure;
  45.       elsif (dataadr /= 80) then
  46.         report "Simulation failed" severity failure;
  47.       end if;
  48.     end if;
  49.   end process;
  50. end;
  51.  
  52. library IEEE;
  53. use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD_UNSIGNED.all;
  54.  
  55. entity top is -- top-level design for testing
  56.   port(clk, reset:           in     STD_LOGIC;
  57.        writedata, dataadr:   buffer STD_LOGIC_VECTOR(31 downto 0);
  58.        memwrite:             buffer STD_LOGIC);
  59. end;
  60.  
  61. architecture test of top is
  62.   component mips
  63.     port(clk, reset:        in  STD_LOGIC;
  64.          pc:                out STD_LOGIC_VECTOR(31 downto 0);
  65.          instr:             in  STD_LOGIC_VECTOR(31 downto 0);
  66.          memwrite:          out STD_LOGIC;
  67.          aluout, writedata: out STD_LOGIC_VECTOR(31 downto 0);
  68.          readdata:          in  STD_LOGIC_VECTOR(31 downto 0));
  69.   end component;
  70.   component imem
  71.     port(a:  in  STD_LOGIC_VECTOR(5 downto 0);
  72.          rd: out STD_LOGIC_VECTOR(31 downto 0));
  73.   end component;
  74.   component dmem
  75.     port(clk, we:  in STD_LOGIC;
  76.          a, wd:    in STD_LOGIC_VECTOR(31 downto 0);
  77.          rd:       out STD_LOGIC_VECTOR(31 downto 0));
  78.   end component;
  79.   signal pc, instr,
  80.          readdata: STD_LOGIC_VECTOR(31 downto 0);
  81. begin
  82.   -- instantiate processor and memories
  83.   mips1: mips port map(clk, reset, pc, instr, memwrite, dataadr,
  84.                        writedata, readdata);
  85.   imem1: imem port map(pc(7 downto 2), instr);
  86.   dmem1: dmem port map(clk, memwrite, dataadr, writedata, readdata);
  87. end;
  88.  
  89. library IEEE;
  90. use IEEE.STD_LOGIC_1164.all; use STD.TEXTIO.all;
  91. use IEEE.NUMERIC_STD_UNSIGNED.all;
  92.  
  93. entity dmem is -- data memory
  94.   port(clk, we:  in STD_LOGIC;
  95.        a, wd:    in STD_LOGIC_VECTOR(31 downto 0);
  96.        rd:       out STD_LOGIC_VECTOR(31 downto 0));
  97. end;
  98.  
  99. architecture behave of dmem is
  100. begin
  101.   process is
  102.     type ramtype is array (63 downto 0) of STD_LOGIC_VECTOR(31 downto 0);
  103.     variable mem: ramtype;
  104.   begin
  105.     -- read or write memory
  106.     loop
  107.       if clk'event and clk = '1' then
  108.           if (we = '1') then mem(to_integer(a(7 downto 2))) := wd;
  109.           end if;
  110.       end if;
  111.       rd <= mem(to_integer(a(7 downto 2)));
  112.       wait on clk, a;
  113.     end loop;
  114.  
  115.   end process;
  116. end;
  117.  
  118. library IEEE;
  119. use IEEE.STD_LOGIC_1164.all; use STD.TEXTIO.all;
  120. use IEEE.NUMERIC_STD_UNSIGNED.all;  
  121.  
  122. entity imem is -- instruction memory
  123.   port(a:  in  STD_LOGIC_VECTOR(5 downto 0);
  124.        rd: out STD_LOGIC_VECTOR(31 downto 0));
  125. end;
  126.  
  127. architecture behave of imem is
  128. begin
  129.   process is
  130.     file mem_file: TEXT;
  131.     variable L: line;
  132.     variable ch: character;
  133.     variable i, index, result: integer;
  134.     type ramtype is array (63 downto 0) of STD_LOGIC_VECTOR(31 downto 0);
  135.     variable mem: ramtype;
  136.   begin
  137.     -- initialize memory from file
  138.     for i in 0 to 63 loop -- set all contents low
  139.       mem(i) := (others => '0');
  140.     end loop;
  141.     index := 0;
  142.     FILE_OPEN(mem_file, "C:/docs/DDCA2e/hdl/memfile.dat", READ_MODE);
  143.     while not endfile(mem_file) loop
  144.       readline(mem_file, L);
  145.       result := 0; 
  146.       for i in 1 to 8 loop
  147.         read(L, ch);
  148.         if '0' <= ch and ch <= '9' then
  149.             result := character'pos(ch) - character'pos('0');
  150.         elsif 'a' <= ch and ch <= 'f' then
  151.            result := character'pos(ch) - character'pos('a')+10;
  152.         else report "Format error on line " & integer'image(index)
  153.              severity error;
  154.         end if;
  155.         mem(index)(35-i*4 downto 32-i*4) :=to_std_logic_vector(result,4);
  156.       end loop;
  157.       index := index + 1;
  158.     end loop;
  159.  
  160.     -- read memory
  161.     loop
  162.       rd <= mem(to_integer(a));
  163.       wait on a;
  164.     end loop;
  165.   end process;
  166. end;
  167.  
  168. library IEEE; use IEEE.STD_LOGIC_1164.all;
  169.  
  170. entity mips is -- single cycle MIPS processor
  171.   port(clk, reset:        in  STD_LOGIC;
  172.        pc:                out STD_LOGIC_VECTOR(31 downto 0);
  173.        instr:             in  STD_LOGIC_VECTOR(31 downto 0);
  174.        memwrite:          out STD_LOGIC;
  175.        aluout, writedata: out STD_LOGIC_VECTOR(31 downto 0);
  176.        readdata:          in  STD_LOGIC_VECTOR(31 downto 0));
  177. end;
  178.  
  179. architecture struct of mips is
  180.   component controller
  181.     port(op, funct:          in  STD_LOGIC_VECTOR(5 downto 0);
  182.          zero:               in  STD_LOGIC;
  183.          memtoreg, memwrite: out STD_LOGIC;
  184.          pcsrc, alusrc:      out STD_LOGIC;
  185.          regdst, regwrite:   out STD_LOGIC;
  186.          jump:               out STD_LOGIC;
  187.          alucontrol:         out STD_LOGIC_VECTOR(2 downto 0));
  188.   end component;
  189.   component datapath
  190.     port(clk, reset:        in  STD_LOGIC;
  191.          memtoreg, pcsrc:   in  STD_LOGIC;
  192.          alusrc, regdst:    in  STD_LOGIC;
  193.          regwrite, jump:    in  STD_LOGIC;
  194.          alucontrol:        in  STD_LOGIC_VECTOR(2 downto 0);
  195.          zero:              out STD_LOGIC;
  196.          pc:                buffer STD_LOGIC_VECTOR(31 downto 0);
  197.          instr:             in STD_LOGIC_VECTOR(31 downto 0);
  198.          aluout, writedata: buffer STD_LOGIC_VECTOR(31 downto 0);
  199.          readdata:          in  STD_LOGIC_VECTOR(31 downto 0));
  200.   end component;
  201.   signal memtoreg, alusrc, regdst, regwrite, jump, pcsrc: STD_LOGIC;
  202.   signal zero: STD_LOGIC;
  203.   signal alucontrol: STD_LOGIC_VECTOR(2 downto 0);
  204. begin
  205.   cont: controller port map(instr(31 downto 26), instr(5 downto 0),
  206.                             zero, memtoreg, memwrite, pcsrc, alusrc,
  207.                             regdst, regwrite, jump, alucontrol);
  208.   dp: datapath port map(clk, reset, memtoreg, pcsrc, alusrc, regdst,
  209.                         regwrite, jump, alucontrol, zero, pc, instr,
  210.                         aluout, writedata, readdata);
  211. end;
  212.  
  213. library IEEE; use IEEE.STD_LOGIC_1164.all;
  214.  
  215. entity controller is -- single cycle control decoder
  216.   port(op, funct:          in  STD_LOGIC_VECTOR(5 downto 0);
  217.        zero:               in  STD_LOGIC;
  218.        memtoreg, memwrite: out STD_LOGIC;
  219.        pcsrc, alusrc:      out STD_LOGIC;
  220.        regdst, regwrite:   out STD_LOGIC;
  221.        jump:               out STD_LOGIC;
  222.        alucontrol:         out STD_LOGIC_VECTOR(2 downto 0));
  223. end;
  224.  
  225.  
  226. architecture struct of controller is
  227.   component maindec
  228.     port(op:                 in  STD_LOGIC_VECTOR(5 downto 0);
  229.          memtoreg, memwrite: out STD_LOGIC;
  230.          branch, alusrc:     out STD_LOGIC;
  231.          regdst, regwrite:   out STD_LOGIC;
  232.          jump:               out STD_LOGIC;
  233.          aluop:              out STD_LOGIC_VECTOR(1 downto 0));
  234.   end component;
  235.   component aludec
  236.     port(funct:      in  STD_LOGIC_VECTOR(5 downto 0);
  237.          aluop:      in  STD_LOGIC_VECTOR(1 downto 0);
  238.          alucontrol: out STD_LOGIC_VECTOR(2 downto 0));
  239.   end component;
  240.   signal aluop:  STD_LOGIC_VECTOR(1 downto 0);
  241.   signal branch: STD_LOGIC;
  242. begin
  243.   md: maindec port map(op, memtoreg, memwrite, branch,
  244.                        alusrc, regdst, regwrite, jump, aluop);
  245.   ad: aludec port map(funct, aluop, alucontrol);
  246.  
  247.   pcsrc <= branch and zero;
  248. end;
  249.  
  250. library IEEE; use IEEE.STD_LOGIC_1164.all;
  251.  
  252. entity maindec is -- main control decoder
  253.   port(op:                 in  STD_LOGIC_VECTOR(5 downto 0);
  254.        memtoreg, memwrite: out STD_LOGIC;
  255.        branch, alusrc:     out STD_LOGIC;
  256.        regdst, regwrite:   out STD_LOGIC;
  257.        jump:               out STD_LOGIC;
  258.        aluop:              out STD_LOGIC_VECTOR(1 downto 0));
  259. end;
  260.  
  261. architecture behave of maindec is
  262.   signal controls: STD_LOGIC_VECTOR(8 downto 0);
  263. begin
  264.   process(all) begin
  265.     case op is
  266.       when "000000" => controls <= "110000010"; -- RTYPE
  267.       when "100011" => controls <= "101001000"; -- LW
  268.       when "101011" => controls <= "001010000"; -- SW
  269.       when "000100" => controls <= "000100001"; -- BEQ
  270.       when "001000" => controls <= "101000000"; -- ADDI
  271.       when "000010" => controls <= "000000100"; -- J
  272.       when others   => controls <= "---------"; -- illegal op
  273.     end case;
  274.   end process;
  275.  
  276.   (regwrite, regdst, alusrc, branch, memwrite,
  277.    memtoreg, jump, aluop(1 downto 0)) <= controls;
  278. end;
  279.  
  280. library IEEE; use IEEE.STD_LOGIC_1164.all;
  281.  
  282. entity aludec is -- ALU control decoder
  283.   port(funct:      in  STD_LOGIC_VECTOR(5 downto 0);
  284.        aluop:      in  STD_LOGIC_VECTOR(1 downto 0);
  285.        alucontrol: out STD_LOGIC_VECTOR(2 downto 0));
  286. end;
  287.  
  288. architecture behave of aludec is
  289. begin
  290.   process(all) begin
  291.     case aluop is
  292.       when "00" => alucontrol <= "010"; -- add (for lw/sw/addi)
  293.       when "01" => alucontrol <= "110"; -- sub (for beq)
  294.       when others => case funct is      -- R-type instructions
  295.                          when "100000" => alucontrol <= "010"; -- add
  296.                          when "100010" => alucontrol <= "110"; -- sub
  297.                          when "100100" => alucontrol <= "000"; -- and
  298.                          when "100101" => alucontrol <= "001"; -- or
  299.                          when "101010" => alucontrol <= "111"; -- slt
  300.                          when others   => alucontrol <= "---"; -- ???
  301.                      end case;
  302.     end case;
  303.   end process;
  304. end;
  305.  
  306. library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all;
  307.  
  308. entity datapath is  -- MIPS datapath
  309.   port(clk, reset:        in  STD_LOGIC;
  310.        memtoreg, pcsrc:   in  STD_LOGIC;
  311.        alusrc, regdst:    in  STD_LOGIC;
  312.        regwrite, jump:    in  STD_LOGIC;
  313.        alucontrol:        in  STD_LOGIC_VECTOR(2 downto 0);
  314.        zero:              out STD_LOGIC;
  315.        pc:                buffer STD_LOGIC_VECTOR(31 downto 0);
  316.        instr:             in  STD_LOGIC_VECTOR(31 downto 0);
  317.        aluout, writedata: buffer STD_LOGIC_VECTOR(31 downto 0);
  318.        readdata:          in  STD_LOGIC_VECTOR(31 downto 0));
  319. end;
  320.  
  321. architecture struct of datapath is
  322.   component alu
  323.     port(a, b:       in  STD_LOGIC_VECTOR(31 downto 0);
  324.          alucontrol: in  STD_LOGIC_VECTOR(2 downto 0);
  325.          result:     buffer STD_LOGIC_VECTOR(31 downto 0);
  326.          zero:       out STD_LOGIC);
  327.   end component;
  328.   component regfile
  329.     port(clk:           in  STD_LOGIC;
  330.          we3:           in  STD_LOGIC;
  331.          ra1, ra2, wa3: in  STD_LOGIC_VECTOR(4 downto 0);
  332.          wd3:           in  STD_LOGIC_VECTOR(31 downto 0);
  333.          rd1, rd2:      out STD_LOGIC_VECTOR(31 downto 0));
  334.   end component;
  335.   component adder
  336.     port(a, b: in  STD_LOGIC_VECTOR(31 downto 0);
  337.          y:    out STD_LOGIC_VECTOR(31 downto 0));
  338.   end component;
  339.   component sl2
  340.     port(a: in  STD_LOGIC_VECTOR(31 downto 0);
  341.          y: out STD_LOGIC_VECTOR(31 downto 0));
  342.   end component;
  343.   component signext
  344.     port(a: in  STD_LOGIC_VECTOR(15 downto 0);
  345.          y: out STD_LOGIC_VECTOR(31 downto 0));
  346.   end component;
  347.   component flopr generic(width: integer);
  348.     port(clk, reset: in  STD_LOGIC;
  349.          d:          in  STD_LOGIC_VECTOR(width-1 downto 0);
  350.          q:          out STD_LOGIC_VECTOR(width-1 downto 0));
  351.   end component;
  352.   component mux2 generic(width: integer);
  353.     port(d0, d1: in  STD_LOGIC_VECTOR(width-1 downto 0);
  354.          s:      in  STD_LOGIC;
  355.          y:      out STD_LOGIC_VECTOR(width-1 downto 0));
  356.   end component;
  357.   signal writereg:           STD_LOGIC_VECTOR(4 downto 0);
  358.   signal pcjump, pcnext,
  359.          pcnextbr, pcplus4,
  360.          pcbranch:           STD_LOGIC_VECTOR(31 downto 0);
  361.   signal signimm, signimmsh: STD_LOGIC_VECTOR(31 downto 0);
  362.   signal srca, srcb, result: STD_LOGIC_VECTOR(31 downto 0);
  363. begin
  364.   -- next PC logic
  365.   pcjump <= pcplus4(31 downto 28) & instr(25 downto 0) & "00";
  366.   pcreg: flopr generic map(32) port map(clk, reset, pcnext, pc);
  367.   pcadd1: adder port map(pc, X"00000004", pcplus4);
  368.   immsh: sl2 port map(signimm, signimmsh);
  369.   pcadd2: adder port map(pcplus4, signimmsh, pcbranch);
  370.   pcbrmux: mux2 generic map(32) port map(pcplus4, pcbranch,
  371.                                          pcsrc, pcnextbr);
  372.   pcmux: mux2 generic map(32) port map(pcnextbr, pcjump, jump, pcnext);
  373.  
  374.   -- register file logic
  375.   rf: regfile port map(clk, regwrite, instr(25 downto 21),
  376.                        instr(20 downto 16), writereg, result, srca,
  377.                 writedata);
  378.   wrmux: mux2 generic map(5) port map(instr(20 downto 16),
  379.                                       instr(15 downto 11),
  380.                                       regdst, writereg);
  381.   resmux: mux2 generic map(32) port map(aluout, readdata,
  382.                                         memtoreg, result);
  383.   se: signext port map(instr(15 downto 0), signimm);
  384.  
  385.   -- ALU logic
  386.   srcbmux: mux2 generic map(32) port map(writedata, signimm, alusrc,
  387.                                          srcb);
  388.   mainalu: alu port map(srca, srcb, alucontrol, aluout, zero);
  389. end;
  390.  
  391. library IEEE; use IEEE.STD_LOGIC_1164.all;
  392. use IEEE.NUMERIC_STD_UNSIGNED.all;
  393.  
  394. entity regfile is -- three-port register file
  395.   port(clk:           in  STD_LOGIC;
  396.        we3:           in  STD_LOGIC;
  397.        ra1, ra2, wa3: in  STD_LOGIC_VECTOR(4 downto 0);
  398.        wd3:           in  STD_LOGIC_VECTOR(31 downto 0);
  399.        rd1, rd2:      out STD_LOGIC_VECTOR(31 downto 0));
  400. end;
  401.  
  402. architecture behave of regfile is
  403.   type ramtype is array (31 downto 0) of STD_LOGIC_VECTOR(31 downto 0);
  404.   signal mem: ramtype;
  405. begin
  406.   -- three-ported register file
  407.   -- read two ports combinationally
  408.   -- write third port on rising edge of clock
  409.   -- register 0 hardwired to 0
  410.   -- note: for pipelined processor, write third port
  411.   -- on falling edge of clk
  412.   process(clk) begin
  413.     if rising_edge(clk) then
  414.        if we3 = '1' then mem(to_integer(wa3)) <= wd3;
  415.        end if;
  416.     end if;
  417.   end process;
  418.   process(all) begin
  419.     if (to_integer(ra1) = 0) then rd1 <= X"00000000"; -- register 0 holds 0
  420.     else rd1 <= mem(to_integer(ra1));
  421.     end if;
  422.     if (to_integer(ra2) = 0) then rd2 <= X"00000000";
  423.     else rd2 <= mem(to_integer(ra2));
  424.     end if;
  425.   end process;
  426. end;
  427.  
  428. library IEEE; use IEEE.STD_LOGIC_1164.all;
  429. use IEEE.NUMERIC_STD_UNSIGNED.all;
  430.  
  431. entity adder is -- adder
  432.   port(a, b: in  STD_LOGIC_VECTOR(31 downto 0);
  433.        y:    out STD_LOGIC_VECTOR(31 downto 0));
  434. end;
  435.  
  436. architecture behave of adder is
  437. begin
  438.   y <= a + b;
  439. end;
  440.  
  441.  
  442. library IEEE; use IEEE.STD_LOGIC_1164.all;
  443.  
  444. entity sl2 is -- shift left by 2
  445.   port(a: in  STD_LOGIC_VECTOR(31 downto 0);
  446.        y: out STD_LOGIC_VECTOR(31 downto 0));
  447. end;
  448.  
  449. architecture behave of sl2 is
  450. begin
  451.   y <= a(29 downto 0) & "00";
  452. end;
  453.  
  454. library IEEE; use IEEE.STD_LOGIC_1164.all;
  455.  
  456. entity signext is -- sign extender
  457.   port(a: in  STD_LOGIC_VECTOR(15 downto 0);
  458.        y: out STD_LOGIC_VECTOR(31 downto 0));
  459. end;
  460.  
  461. architecture behave of signext is
  462. begin
  463.   y <= X"ffff" & a when a(15) else X"0000" & a;
  464. end;
  465.  
  466. library IEEE; use IEEE.STD_LOGIC_1164.all;  use IEEE.STD_LOGIC_ARITH.all;
  467.  
  468. entity flopr is -- flip-flop with synchronous reset
  469.   generic(width: integer);
  470.   port(clk, reset: in  STD_LOGIC;
  471.        d:          in  STD_LOGIC_VECTOR(width-1 downto 0);
  472.        q:          out STD_LOGIC_VECTOR(width-1 downto 0));
  473. end;
  474.  
  475. architecture asynchronous of flopr is
  476. begin
  477.   process(clk, reset) begin
  478.     if reset then  q <= (others => '0');
  479.     elsif rising_edge(clk) then
  480.       q <= d;
  481.     end if;
  482.   end process;
  483. end;
  484.  
  485. library IEEE; use IEEE.STD_LOGIC_1164.all;
  486.  
  487. entity mux2 is -- two-input multiplexer
  488.   generic(width: integer);
  489.   port(d0, d1: in  STD_LOGIC_VECTOR(width-1 downto 0);
  490.        s:      in  STD_LOGIC;
  491.        y:      out STD_LOGIC_VECTOR(width-1 downto 0));
  492. end;
  493.  
  494. architecture behave of mux2 is
  495. begin
  496.   y <= d1 when s else d0;
  497. end;
  498.  
  499.  
  500. library IEEE; use IEEE.STD_LOGIC_1164.all;
  501. use IEEE.NUMERIC_STD_UNSIGNED.all;
  502.  
  503. entity alu is
  504.   port(a, b:       in  STD_LOGIC_VECTOR(31 downto 0);
  505.        alucontrol: in  STD_LOGIC_VECTOR(2 downto 0);
  506.        result:     buffer STD_LOGIC_VECTOR(31 downto 0);
  507.        zero:       out STD_LOGIC);
  508. end;
  509.  
  510. architecture behave of alu is
  511.   signal condinvb, sum: STD_LOGIC_VECTOR(31 downto 0);
  512. begin
  513.   condinvb <= not b when alucontrol(2) else b;
  514.   sum <= a + condinvb + alucontrol(2);
  515.  
  516.   process(all) begin
  517.     case alucontrol(1 downto 0) is
  518.       when "00"   => result <= a and b;
  519.       when "01"   => result <= a or b;
  520.       when "10"   => result <= sum;
  521.       when "11"   => result <= (0 => sum(31), others => '0');
  522.       when others => result <= (others => 'X');
  523.     end case;
  524.   end process;
  525.  
  526.   zero <= '1' when result = X"00000000" else '0';
  527. end;
  528.  
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×