Advertisement
kirill_76rus

vhdl_tmp

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