1、实验分析报告模板实验报告模板 作者: 日期: 同济大学计算机科学与技术系计算机组成原理课程实验报告学 号 1452312 姓 名 冯凯 专 业 计算机科学与技术 授课老师 王力生 日 期 2016.06.18 一、 实验目标1、熟悉Verilog语言的编写。2、掌握计算机的每个部件的构成逻辑及工作原理,计算机各部件之间的连接逻辑,计算机整机的工作原理。 3、掌握CPU功能。4、设计55条单周期指令CPU下板成功2、.在自己的CPU上跑一个汇编程序二、 总体设计1. 作品功能设计及原理说明module comp( input clock, input resetn, output 2:0 r,
2、output 2:0 g, output 1:0 b, output hs, output vs, );2. 硬件逻辑图三、 主要模块设计1.ALUmodule alu( input 31:0 a, input 31:0 b, input 3:0 aluc, output 31:0 r, output zero,/零标志 output carry, / 进位标志位 output negative, / 负数标志位 output overflow / 溢出标志位 ); wire 31:0 d_and = a&b;/0100 wire 31:0 d_or = a|b;/0101 wire 31:0
3、 d_xor = ab;/0110 wire 31:0 d_nor = (a|b);/0111 wire 31:0 d_lui = b15:0,16h0;/100x wire 31:0 d_slt = ab)|(a31&b31&ab); wire 31:0 d_and_or = aluc0?d_or:d_and; wire 31:0 d_xor_nor = aluc0?d_nor:d_xor; wire 31:0 d_and_or_xor_nor = aluc1?d_xor_nor:d_and_or; wire 31:0 d_slt_sltu = aluc0?d_slt:d_sltu; wir
4、e 31:0 d_lui_slt_sltu = aluc1?d_slt_sltu:d_lui; wire 31:0 d_as; wire 31:0 d_sh; wire carry_as; wire negative_as; wire overflow_as; wire carry_sh; addsub32 as32(a,b,aluc0,aluc1,d_as,carry_as,overflow_as); shift shifter(b,a4:0,aluc1,aluc0,d_sh,carry_sh); mux4x32 select_d(d_as,d_and_or_xor_nor,d_lui_sl
5、t_sltu,d_sh,aluc3:2,r); mux4x1 select_carry(carry_as,1b0,1b0,carry_sh,aluc3:2,carry); mux4x1 select_overflow(overflow_as,1b0,1b0,overflow_sh,aluc3:2,overflow); assign zero = |r; assign negative = r31;endmodule 2.regfilemodule regfile( input 4:0 raddr1, input 4:0 raddr2, input 31:0 wdata, input 4:0 w
6、addr, input we, input clk, input rst, output 31:0 radata1, output 31:0 radata2 ); reg 31:0 register0:31; assign radata1=(raddr1=0)?0:registerraddr1; assign radata2=(raddr2=0)?0:registerraddr2; integer i; always (posedge rst or negedge clk)begin if(rst=1) begin for(i=1;i32;i=i+1)begin registeri=0; en
7、d end else begin register0=32b0; if(waddr!=0)&we)begin registerwaddr=wdata; end end endendmodule3.CP0module Coprocessor0( input clk, input4:0 C0adr, input31:0 C0Wdata, input C0Write, input31:0 InteCause, input Interrupt, output InteAccept, output31:0 C0State, output reg31:0 C0Data );parameter EPCadr
8、 = 5h0;parameter Causeadr = 5h1;parameter Stateadr = 5h2;reg31:0 EPC;reg31:0 Cause;reg31:0 State;initial begin State = 32h1; Cause = 32h0; EPC = 32h0;endassign C0State = State;assign InteAccept = (C0Write & (C0adr=Stateadr) & Interrupt & C0Wdata1 | (C0Write & (C0adr=Stateadr) & (C0Write & (C0adr=Cau
9、seadr) & Interrupt & State1;always(posedge clk) begin if(C0Write) begin if(C0adr=EPCadr) begin EPC = C0Wdata; if(Interrupt & State1) begin State = State | 32b10; Cause = InteCause; end end if(C0adr=Stateadr) begin if(Interrupt & C0Wdata1) begin State = C0Wdata | 32b10; Cause = InteCause; end else be
10、gin State = C0Wdata; end end if(C0adr=Causeadr) begin Cause = C0Wdata; end end else begin if(Interrupt & State1) begin State = State | 32b10; Cause = InteCause; end end case(C0adr) EPCadr: begin C0Data = EPC; end Causeadr: begin C0Data = Cause; end Stateadr: begin C0Data = State; end endcaseendendmo
11、dule4.pc_regmodule pc_reg( input clk, input rst, input 31:0 data_in, output reg 31:0 data_out ); always(posedge clk) begin if(rst=1)begin data_out=0; end else begin data_out=data_in; end endendmodule5.mulmodule mul( input 31:0 a, input 31:0 b, input we, input u,/1有符号,0无符号 output 31:0 hi, output 31:0
12、 lo ); reg 32:0 a_bi32:0; integer i; integer j; wire 32:0 ai; wire 32:0 bi; wire 65:0 z; assign ai = u?a31,a:1b0,a; assign bi = u?b31,b:1b0,b; always(*)begin if(we) for(i = 0;i32;i = i+1) for(j = 0;j32;j = j+1) a_biij = aii&bij; for(i = 0;i32;i = i+1) a_bii32 = (aii&bi32); for(j = 0;j32;j = j+1) a_b
13、i32j = (ai32&bij); a_bi3232 = ai32&bi32; end assign z = 33b1,a_bi032,a_bi031:0 + (32b0,a_bi132,a_bi131:0,1b0 + 31b0,a_bi232,a_bi231:0,2b0) + (30b0,a_bi332,a_bi331:0,3b0 + 29b0,a_bi432,a_bi431:0,4b0) + (28b0,a_bi532,a_bi531:0,5b0 + 27b0,a_bi632,a_bi631:0,6b0) + (26b0,a_bi732,a_bi731:0,7b0 + 25b0,a_bi
14、832,a_bi831:0,8b0) + (24b0,a_bi932,a_bi931:0,9b0 + 23b0,a_bi1032,a_bi1031:0,10b0) + (22b0,a_bi1132,a_bi1131:0,11b0 + 21b0,a_bi1232,a_bi1231:0,12b0) + (20b0,a_bi1332,a_bi1331:0,13b0 + 19b0,a_bi1432,a_bi1431:0,14b0) + (18b0,a_bi1532,a_bi1531:0,15b0 + 17b0,a_bi1632,a_bi1631:0,16b0)+ (16b0,a_bi1732,a_bi
15、1731:0,17b0 + 15b0,a_bi1832,a_bi1831:0,18b0) + (14b0,a_bi1932,a_bi1931:0,19b0 + 13b0,a_bi2032,a_bi2031:0,20b0) + (12b0,a_bi2132,a_bi2131:0,21b0 + 11b0,a_bi2232,a_bi2231:0,22b0) + (10b0,a_bi2332,a_bi2331:0,23b0 + 9b0,a_bi2432,a_bi2431:0,24b0) + (8b0,a_bi2532,a_bi2531:0,25b0 + 7b0,a_bi2632,a_bi2631:0,
16、26b0) + (6b0,a_bi2732,a_bi2731:0,27b0 + 5b0,a_bi2832,a_bi2831:0,28b0) + (4b0,a_bi2932,a_bi2931:0,29b0 + 3b0,a_bi3032,a_bi3031:0,30b0) + (2b0,a_bi3132,a_bi3131:0,31b0 + 1b1,a_bi3232,a_bi3231:0,32b0); assign hi = z63:32; assign lo = z31:0;endmodule6.divmodule div( input 31:0 a1,/被除数低位 input 31:0 a2,/被
17、除数高位 input 31:0 b,/除数 input en,/使能 input u,/0无符号,1有符号 output reg 31:0 q,/商 output reg 31:0 r/余数 ); reg 5:0 count;/32 reg 66:0 a;initial begin count=0;endinteger i;always(*)begin if(en=1) begin if(u=0)begin a=2b00,a231:0,a131:0,1b0; a=a-b31:0,33b000000000000000000000000000000000; for(i=0;i32;i=i+1) b
18、egin if (a66+a65=2)begin a0=0; a=a1; a=a+b31:0,33b000000000000000000000000000000000; end else begin a0=1; a=a1; a=a-b31:0,33b000000000000000000000000000000000; end end if(a66+a65=2)begin a0=0; a=a+b31:0,33b000000000000000000000000000000000; end else begin a0=1; end q=a31:0; r=a64:33; end else begin
19、if(a231=b31)begin a=2b00,a231:0,a131:0,1b0; a=a-b31:0,33b000000000000000000000000000000000; end else begin a=2b00,a231:0,a131:0,1b0; a=a+b31:0,33b000000000000000000000000000000000; end for(i=0;i32;i=i+1) begin if (a63!=b31)begin a0=0; a=a1; a=a+b31:0,33b000000000000000000000000000000000; end else be
20、gin a0=1; a=a=0 if(a31=0) z = 1; else z = 0; 2b01:/0 if(a31=1) z = 1; else z = 0; 2b10:/=0 if(a31=1|a=0) z = 1; else z 0 if(a31=0|a!=0) z = 1; else z = 0; endcase endendmodule8.imemmodule instmem( input 31:0 pc, output 31:0 inst ); reg 31:0 a 0:255; initial begin $readmemh(1.txt,a); end assign inst
21、= apc31:2;endmodule9.dmem/ 因lh、lb、sh、sb等指令对dmem做了改动module ram( input clk, input ram_ena, input 1:0 c,/0x lw/sw,10 lh/sh,11 lb/hb input u, input 31:0 addr, input 31:0 data_in, output reg 31:0 data_out ); reg 7:0 a 0:20470; always(posedge clk)begin if(ram_ena) case(c) 2b00:begin aaddr31:2,2b00 = data_
22、in7:0; aaddr31:2,2b00+1 = data_in15:8; aaddr31:2,2b00+2 = data_in23:16; aaddr31:2,2b00+3 = data_in31:24; end 2b10:begin aaddr31:1,1b0 = data_in7:0; aaddr31:1,1b0+1 = data_in15:8; end 2b11:begin aaddr = data_in7:0; end default: begin aaddr = 0; end endcase end always(*)begin case(c) 2b00:begin data_out =aaddr31:2,2b00+3,aaddr31:2,2b00+2,aaddr31:2,2b00+1,aaddr31:2,2b00; end 2b01:begin data_out =aaddr31:2,2b00+3,aaddr31:2,2b00+2,aaddr31:2,2b00+1,aaddr31:2,2b00; end 2b10:begin data_out =16u&aaddr31:1,1b0+17,aaddr31:1,1b0+1,aaddr31:1,1b0; end 2b11:begin data_out =24u&aaddr7,aaddr;