kirill_76rus

mipsmulti

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