国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

中科大OJ Verilog 在線評測題解 100-105

這篇具有很好參考價值的文章主要介紹了中科大OJ Verilog 在線評測題解 100-105。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

近跟著老師學習Verilog,做了中科大的練習題,將答案記錄一下

Q62-99

題在哪兒

Q100 寄存器堆模塊

題目描述

在RV32I中,寄存器堆指32個通用寄存器的集合,具有專門的讀寫端口,可并發(fā)訪問不同寄存器。
中國科學技術大學用什么oj,fpga開發(fā)
我們用5位數代表寄存器的端口號,需要注意的是:當待寫入寄存器端口號為0時,往x0寫入的數據總是被丟棄,因為x0寄存器恒為0,不能對x0寄存器的值進行修改。設置x0寄存器,既可以提供常量0(比如RISC-V用sub rd, x0, rs來實現neg取負數指令),也可以提供一個可以丟棄結果的場所(比如RISC-V使用addi x0, x0, 0實現nop空指令)。
中國科學技術大學用什么oj,fpga開發(fā)
當A1有意義時,其對應指令中的rs1,即第15到19位;同理,當有意義時,A2對應指令中的rs2,即第20到24位;A3對應指令中的rd,即第7到11位。

輸入格式

1.時鐘信號clk 2.位寬為5的待讀取寄存器端口號A1 3.位寬為5的待讀取寄存器端口號A2 4.位寬為5的待寫入寄存器端口號A3 5.位寬為32的待寫入數據WD 6.位寬為1的寄存器寫使能信號WE

輸出格式

1.位寬為32的從A1對應的寄存器中讀出的數據RD1 2.位寬為32的從A2對應的寄存器中讀出的數據RD2

代碼

module top_module(
input         clk,
input  [4:0]  A1,A2,A3,
input  [31:0] WD,
input 	      WE,
output [31:0] RD1,RD2
);
reg [31:0] reg_file[0:31];
//初始化寄存器堆
integer i;
initial
begin
    for(i=0;i<32;i=i+1) reg_file[i] = 0;
end

//寫入寄存器
always@(posedge clk)
begin
	/*待填*/
    if(WE&A3!=0) //A3==0的情況排除?X0一直為0
        reg_file[A3]= WD;
    else ;
end

//讀取寄存器
    assign RD1 = reg_file[A1]/*待填*/;
    assign RD2 = reg_file[A2]/*待填*/;

endmodule

Q101 程序計數器模塊

題目描述

當執(zhí)行一條指令時,首先需要根據PC中存放的指令地址,將指令由內存取到指令寄存器中,此過程稱為取指。

?

PC全稱ProgramCounter(程序計數器),它是計算機處理器中的寄存器,包含當前正在執(zhí)行的指令的地址。

中國科學技術大學用什么oj,fpga開發(fā)
一般情況下,當指令被獲取,程序計數器存儲的地址加四(一條指令有32位,為4字節(jié))。當遇到跳轉指令(jal,jalr)或者滿足分支跳轉指令(所有B類指令)的跳轉條件時,則將程序計數器的內容設置為轉移指令規(guī)定的地址。

輸入格式

1.時鐘信號clk 2.復位鍵rst,當rst為1時將PC置零 3.位寬為1的跳轉信號JUMP,當JUMP為1時將PC設為JUMP_PC 4.位寬為32的待跳轉的地址JUMP_PC

輸出格式

位寬為32的當前周期需要執(zhí)行指令的地址pc

代碼

module top_module(
input              clk,
input              rst,
input              JUMP,
input       [31:0] JUMP_PC,
output reg  [31:0] pc);
wire [31:0] pc_plus4;
assign pc_plus4 = pc + 32'h4;
//計算PC
always@(posedge clk or posedge rst)
begin
	/*待填*/
    if(rst)
       pc<=0;
    else if(JUMP)
        pc<=JUMP_PC;
    else
         pc<=pc_plus4;
        
end
endmodule

Q102 立即數擴展模塊

題目描述

中國科學技術大學用什么oj,fpga開發(fā)
通過上圖可知,不同類型的指令,立即數的位置不同,我們需要從原始的指令中提取出順序正確的立即數,并依照指令的類型對立即數做相應擴展。
通過了解各指令的具體作用和指令格式,我們能得到下表:
中國科學技術大學用什么oj,fpga開發(fā)
注:符號位擴展就是對不足32位的數,在高位擴展符號位至32位的操作(符號位是1則填1,符號位為0則填0)

輸入格式

位寬為32的指令inst

輸出格式

經過擴展的32位立即數out

代碼

module top_module(
input 	    [31:0] inst,
output reg	[31:0] out
);
wire	[6:0] opcode;
assign	opcode= inst[6:0];
//立即數擴展
always@(*)
begin
	case(opcode)
          /*待填*/
        7'b0010111:out<={inst[31:12],12'b0};
        7'b0110111:out<={inst[31:12],12'b0};
        7'b1100011:out<={{20{inst[31]}},inst[7],inst[30:25],inst[11:8],1'b0};
        7'b1101111:out<={{12{inst[31]}},inst[19:12],inst[20],inst[30:21],1'b0};
        7'b1100111:out<={{12{inst[31]}},inst[19:12],inst[20],inst[30:21],1'b0};
        7'b0000011:out<={{20{inst[31]}},inst[31:20]};
        7'b0100011:out<={{20{inst[31]}},inst[31:25],inst[11:7]};
        7'b0010011:out<={{20{inst[31]}},inst[31:20]};
        default:out<=32'h0;
	endcase
end 
endmodule

Q103 分支判斷模塊

題目描述

RV32I基礎指令集中提供了6條B型指令,分支判斷模塊負責判斷跳轉條件是否滿足,需要分支跳轉時產生分支信號。
中國科學技術大學用什么oj,fpga開發(fā)
如上圖,Type是代表不同比較類型的3位編碼,其與輸入輸出的關系如下表:
中國科學技術大學用什么oj,fpga開發(fā)
注:Type并不等價于B類指令中的funct3(功能碼),只是控制器處理指令后輸出的一個信號。因為beq的funct3為000,而我們在編寫代碼時,把0作為默認值;當信號為0時,我們不做操作,這樣可以有利于增強代碼的容錯率。

輸入格式

1.位寬為32的(從寄存器中讀取的)待比較數REG1 2.位寬為32的(從寄存器中讀取的)待比較數REG2 3.位寬為3的Type,用于區(qū)分兩個待比較數比較的類型

輸出格式

位寬為1的分支跳轉信號BrE

代碼

module top_module(         
input [31:0]	REG1,
input [31:0] 	REG2,
input [2:0]		Type,
output     reg     BrE
);
wire signed 	[31:0] signed_REG1;
wire signed 	[31:0] signed_REG2;
wire unsigned 	[31:0] unsigned_REG1;
wire unsigned 	[31:0] unsigned_REG2;

assign signed_REG1 = REG1;
assign signed_REG2 = REG2; 
assign unsigned_REG1 = REG1;
assign unsigned_REG2 = REG2; 
always@(*)
begin
	case(Type)
    	/*待填*/ 
        3'b010:BrE<=(signed_REG1==signed_REG2?1:0);
        3'b011:BrE<=(signed_REG1!=signed_REG2?1:0);
        3'b100:BrE<=(signed_REG1<signed_REG2?1:0);
        3'b101:BrE<=(signed_REG1>=signed_REG2?1:0);
        3'b110:BrE<=(unsigned_REG1<unsigned_REG2?1:0);
        3'b111:BrE<=(unsigned_REG1>=unsigned_REG2?1:0);
        default:BrE<=1'b0;
	endcase
end
endmodule

Q104 ALU模塊

題目描述

ALU全稱Arithmetic and Logic Unit,即算數邏輯單元,是數字計算機中執(zhí)行加、減等算術運算,執(zhí)行與、或等邏輯運算,以及執(zhí)行比較、移位、傳送等操作的功能部件。
中國科學技術大學用什么oj,fpga開發(fā)
ALU模塊如上圖,其中func是區(qū)分操作類型的4位編碼,其與輸入輸出的對應如下表:
中國科學技術大學用什么oj,fpga開發(fā)
注:上表只是一種設計,設計不唯一

輸入格式

1.位寬為32的源操作數SrcA 2.位寬為32的源操作數SrcB 3.位寬為4的func,用于區(qū)分操作類型

輸出格式

位寬為32的運算結果ALUout

代碼

module top_module(
input [31:0] SrcA,SrcB,
input [3:0]  func,
output reg [31:0] ALUout
);

wire signed [31:0] signed_a;
wire signed [31:0] signed_b;
wire unsigned 	[31:0] unsigned_a;
wire unsigned 	[31:0] unsigned_b;

assign unsigned_a = SrcA;
assign unsigned_b = SrcB; 
assign signed_a = SrcA;
assign signed_b = SrcB;

always@(*)
begin
  case(func)
		/*待填*/
      4'b0000:ALUout<=signed_a+signed_b;
      4'b1000:ALUout<=signed_a-signed_b;
      4'b0001:ALUout<=signed_a<<signed_b[4:0];
      4'b0010:ALUout<=signed_a<signed_b?1:0;
      4'b0011:ALUout<=unsigned_a<unsigned_b?1:0;
      4'b0100:ALUout<=signed_a^signed_b;
      4'b0101:ALUout<=signed_a>>signed_b[4:0];
      4'b1101:ALUout<=signed_a>>>signed_b[4:0];
      4'b0110:ALUout<=signed_a|signed_b;
      4'b0111:ALUout<=1'b0;
      4'b1001:ALUout<=1'b0;
      4'b1010:ALUout<=1'b0;
      4'b1011:ALUout<=1'b0;
      4'b1100:ALUout<=1'b0;
      4'b1110:ALUout<=signed_b;
      4'b1111:ALUout<=1'b0;
	endcase
end 

endmodule

Q105 存儲器

題目描述

存儲器模塊包括指令存儲器和數據存儲器,其中指令存儲器用于存放指令,只讀;數據存儲器用于存放數據,可讀可寫;指令存儲器按字節(jié)編址,按字讀??;數據存儲器按字節(jié)編址,可以完成對字、半字、字節(jié)的對齊存取。
中國科學技術大學用什么oj,fpga開發(fā)
因為指令存儲器的容量有限(本實驗中為16KB,可存儲4K條指令),指令長度為32bit(即4B),因此為了判斷地址是否有效,我們需要判斷im_addr的31至14位以及1至0位是否為0。當im_addr有效時,im_dout輸出地址對應的指令,否則輸出全0。
中國科學技術大學用什么oj,fpga開發(fā)
區(qū)分讀取類型的3位信號dm_rd_ctrl與讀取類型的關系如下:
中國科學技術大學用什么oj,fpga開發(fā)
區(qū)分寫入類型的2位信號dm_wr_ctrl與寫入類型的關系如下:
中國科學技術大學用什么oj,fpga開發(fā)
數據寫入時,由于需要對齊,數據不能跨字(即不能跨越兩個32bit的單元)。在代碼中,我們采用了四位的輔助信號byte_en,對于待覆寫的32bit的單元mem[dm_addr[13:2]],我們可以把其看作四個一字節(jié)(8bit)寬度的單位,對應byte_en的四位,對應位為1表示該字節(jié)需要覆寫,反之不需要,具體如下:
中國科學技術大學用什么oj,fpga開發(fā)
本系列實驗使用哈佛體系結構設計,指令和數據分開存儲,但地址空間是重疊的,所以設計verilog代碼時可以合并成一個模塊。

輸入格式

1.位寬為32bit的地址im_addr 2.位寬為32bit的地址dm_addr 3.位寬為32bit的寫入數據dm_din 4.區(qū)分讀取類型的3位信號dm_rd_ctrl 5.區(qū)分寫入類型的2位信號dm_wr_ctrl;

輸出格式

1.位寬為32bit的指令im_dout 2.位寬為32bit的讀出數據dm_dout文章來源地址http://www.zghlxwxcb.cn/news/detail-780395.html

代碼

module top_module(
input           clk,
input   [31:0]  im_addr,
output  [31:0]  im_dout,
input   [2:0]   dm_rd_ctrl,
input   [1:0]   dm_wr_ctrl,
input   [31:0]  dm_addr,
input   [31:0]  dm_din,
output reg  [31:0]  dm_dout
);

reg     [3:0]   byte_en;
reg     [31:0]  mem[0:4095];
reg     [31:0]  mem_out;
integer i;

initial
begin
    for(i=0;i<4095;i=i+1) mem[i] = 0;
end

initial
begin
  $readmemh("./problem/inst.dat",mem);
end

    assign im_dout = ((|im_addr[31:14]==0) &(|im_addr[1:0]==0))?mem[im_addr[13:2]]:32'b0;/*待填*/
//由于不能跨單位讀取數據,地址最低兩位的數值決定了當前單位能讀取到的數據,即mem_out
always@(*)
begin
    case(dm_addr[1:0])
        2'b00:  mem_out = mem[dm_addr[13:2]][31:0];
        2'b01:  mem_out = {8'h0,mem[dm_addr[13:2]][31:8]};
        2'b10:  mem_out = {16'h0,mem[dm_addr[13:2]][31:16]};
        2'b11:  mem_out = {24'h0,mem[dm_addr[13:2]][31:24]};
    endcase
end

always@(*)
begin
    case(dm_rd_ctrl)                                         
    /*待填*/
        3'b001:  dm_dout = {{24{mem_out[7]}},mem_out[7:0]};
        3'b010:  dm_dout = {24'h0,mem_out[7:0]};
        3'b011:  dm_dout = {{16{mem_out[15]}},mem_out[15:0]};
        3'b100:  dm_dout = {16'h0,mem_out[15:0]};
    	3'b101:	 dm_dout = mem_out;
    	default:  dm_dout=32'b0;  
    endcase
end

always@(*)
begin
    if(dm_wr_ctrl == 2'b11)
        byte_en = 4'b1111;
    else if(dm_wr_ctrl == 2'b10)
    begin
        if(dm_addr[1] == 1'b1) 
            byte_en = 4'b1100;
        else
            byte_en = 4'b0011;
    end
    else if(dm_wr_ctrl == 2'b01)
    begin
        case(dm_addr[1:0])
        2'b00:  byte_en = 4'b0001;
        2'b01:  byte_en = 4'b0010;
        2'b10:  byte_en = 4'b0100;
        2'b11:  byte_en = 4'b1000;
        endcase
    end
    else
        byte_en = 4'b0000;
end

always@(posedge clk)
begin
    if((byte_en != 1'b0)&&(dm_addr[30:12]==19'b0))
    begin
        case(byte_en)
        	/*待填*/
            4'b0001:  mem[dm_addr[13:2]][7:0] =dm_din[7:0];
            4'b0010:  mem[dm_addr[13:2]][15:8] =dm_din[15:8];
            4'b0100:  mem[dm_addr[13:2]][24:16] =dm_din[24:16];
            4'b1000:  mem[dm_addr[13:2]][31:17] =dm_din[31:17];
            4'b0011:  mem[dm_addr[13:2]][15:0] =dm_din[15:0];
            4'b1100:  mem[dm_addr[13:2]][31:16] =dm_din[31:16];
            4'b1111:  mem[dm_addr[13:2]] =dm_din;
			default:  ;
        endcase
    end
end
endmodule

到了這里,關于中科大OJ Verilog 在線評測題解 100-105的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包