kirill_76rus

vhdl_tmp

Jun 10th, 2021
513
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 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