日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

单周期十条指令CPU设计与verilog实现(Modelsim)

發(fā)布時間:2023/11/28 生活经验 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 单周期十条指令CPU设计与verilog实现(Modelsim) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

  • 一、實(shí)驗?zāi)康?/li>
  • 二、實(shí)驗內(nèi)容
  • 三、實(shí)驗原理
    • 1. 規(guī)定
    • 2. 原理圖
  • 四、實(shí)驗步驟
    • 1. CPU各部件實(shí)現(xiàn)
      • pc
      • insMem
      • acc
      • alu
      • cu
      • dataMem
    • 2. CPU例化實(shí)現(xiàn)
    • 3. 編寫測試文件
    • 4. 仿真結(jié)果及分析
      • 1. 清除累加器指令CL
      • 2. 累加器取反指令COM
      • 3. 算術(shù)右移一位指令SHR
      • 4. 循環(huán)左移一位指令CSL
      • 5. 加法指令A(yù)DD
      • 6. 存數(shù)指令STA
      • 7. 取數(shù)指令LDA
      • 8. 無條件轉(zhuǎn)移指令JMP
      • 9. 有條件轉(zhuǎn)移指令BAN
      • 10. 停機(jī)指令STP


一、實(shí)驗?zāi)康?/h1>

通過設(shè)計并實(shí)現(xiàn)支持 10 條指令的CPU,進(jìn)一步理解和掌握CPU設(shè)計的基本原理和過程。



二、實(shí)驗內(nèi)容

設(shè)計和實(shí)現(xiàn)一個支持如下十條指令的單周期CPU。

非訪存指令

  • 清除累加器指令CLA
  • 累加器取反指令COM
  • 算術(shù)右移一位指令SHR:將累加器 ACC中的數(shù)右移一位,結(jié)果放回 ACC
  • 循環(huán)左移一位指令CSL:對累加器中的數(shù)據(jù)進(jìn)行操作
  • 停機(jī)指令STP

訪存指令

  • 加法指令ADD X:[X] + [ACC] –>ACC,X為存儲器地址,直接尋址
  • 存數(shù)指令STA X,采用直接尋址方式
  • 取數(shù)指令LDA X,采用直接尋址

轉(zhuǎn)移類指令

  • 無條件轉(zhuǎn)移指令JMP imm:signExt(imm)->PC
  • 有條件轉(zhuǎn)移(負(fù)則轉(zhuǎn))指令BAN X:ACC 最高位為 1 則(PC)+X->PC,否則 PC 不變


三、實(shí)驗原理

1. 規(guī)定

  1. 機(jī)器字長、指令字長和存儲字長均為16位

  2. 指令格式為:

  3. 指令及其操作碼對照表

    非訪存指令訪存指令轉(zhuǎn)移類指令
    清除累加器指令CLA0000加法指令A(yù)DD0100無條件轉(zhuǎn)移指令JMP0111
    累加器取反指令COM0001存數(shù)指令STA0101有條件轉(zhuǎn)移指令BAN 1000
    算術(shù)右移一位指令SHR0010取數(shù)指令LDA0110
    循環(huán)左移一位指令CSL0011
    停機(jī)指令STP: 1001

2. 原理圖



四、實(shí)驗步驟

1. CPU各部件實(shí)現(xiàn)


pc

輸入:

clkrststopctuct
時鐘時鐘停機(jī)條件轉(zhuǎn)移無條件轉(zhuǎn)移

輸出:

offsetpc
12位轉(zhuǎn)移指令偏移量12位指令地址碼
//pc
module pc(input wire clk, rst, stop, ct, uct, //時鐘、重置、停機(jī)、條件轉(zhuǎn)移、無條件轉(zhuǎn)移input wire [11:0] offset,  //12位轉(zhuǎn)移指令偏移量output reg [11:0] pc  //12位指令地址碼  
);assign stop = 0;  //初始化開機(jī)狀態(tài)// assign clk = (stop==1)?1'bz:0; //停機(jī)則將clk置0always@(posedge clk) beginif(rst == 1)pc = 0;elsepc = pc + 1;endalways@(negedge clk) beginif(uct == 1)  //無條件轉(zhuǎn)移pc = offset-1;if(ct == 1)  //條件轉(zhuǎn)移pc = pc+offset-1;endendmodule

insMem

輸入:

addr
12位指令地址碼

輸出:

Ins
16位指令
//insMem
module insMem(input wire [11:0] addr,  //12位指令地址碼output wire [15:0] Ins  //16位指令
);reg[15:0] insMem[4096:0];  //2^12個存儲單元,每個存儲單元16位initial begininsMem[0] = 16'b0000000000000000;    //0000 0000 0000 0000  清除累加器指令CLAinsMem[1] = 16'b0001000000000000;    //0001 0000 0000 0000  累加器取反指令COMinsMem[2] = 16'b0010000000000000;    //0010 0000 0000 0000  算術(shù)右移一位指令SHRinsMem[3] = 16'b0011000000000000;    //0011 0000 0000 0000  循環(huán)左移一位指令CSLinsMem[4] = 16'b0100000000000001 ;   //0100 0000 0000 0001  加法指令A(yù)DDinsMem[5] = 16'b0101000000000000;    //0101 0000 0000 0000  存數(shù)指令STAinsMem[6] = 16'b0110000000000000;    //0110 0000 0000 0000  取數(shù)指令LDAinsMem[7] = 16'b0111000000001001;    //0111 0000 0000 1001  無條件轉(zhuǎn)移指令JMPinsMem[9] = 16'b1000000000001001;    //1000 0000 0000 1001  有條件轉(zhuǎn)移BANinsMem[10] = 16'b100100000000000;    //1111 0000 0000 0000  停機(jī)指令STPendassign Ins = insMem[addr];endmodule

acc

輸入:

clkacc_wrdata_in
時鐘acc讀寫控制16位輸入數(shù)據(jù)

輸出:

data_out
16位輸出數(shù)據(jù)
//acc
module acc(input wire clk, acc_wr, //時鐘、acc讀寫控制input wire [15:0] data_in,  //16位輸入數(shù)據(jù)output wire [15:0] data_out //16位輸出數(shù)據(jù)
);reg [15:0] acc; //16位accinitial beginacc = 1;  //acc初始化1endassign data_out = acc; always@(negedge clk) beginif(acc_wr == 1)acc = data_in;endendmodule

alu

輸入:

in1in2alu_op
操作數(shù)1操作數(shù)2操作選擇信號

輸出:

ctZ
條件轉(zhuǎn)移結(jié)果
//alu
module alu(input wire [15:0] in1, in2,   //操作數(shù)in1和in2input wire [3:0] alu_op,  //操作選擇信號alu_opoutput reg ct, //條件轉(zhuǎn)移ctoutput reg [15:0] Z   //Z
);initial beginct = 0;Z = 0;  //初始化結(jié)果Z為0endalways@* begincase (alu_op)4'b0000: Z = 0;   //清除累加器指令CLA4'b0001: Z = ~in1;    //累加器取反指令COM    4'b0010: Z = in1[15] == 1 ? {1'b1, in1[15:1]} : {1'b0, in1[15:1]};    //算術(shù)右移一位指令SHR4'b0011: Z = {in1[14:0], in1[15]};    //循環(huán)左移一位指令CSL4'b0100: Z = in1 + in2;   //加法指令A(yù)DD4'b0101: Z = in1;    //存數(shù)指令STA4'b0110: Z = in2;   //取數(shù)指令LDA4'b1000: ct = in1[15]==1?1:0;   //有條件轉(zhuǎn)移BAN4'b1001: ;    //停機(jī)指令endcaseendendmodule

cu

輸入:

operate
4位指令操作碼

輸出:

stopuctacc_wrdataMem_wralu_op
停機(jī)信號非條件轉(zhuǎn)移uctacc讀寫控制數(shù)據(jù)存儲器讀寫控制alu操作選擇
//cu
module cu(input wire [3:0] operate,    //4位指令操作碼output reg stop, uct, acc_wr, dataMem_wr, //停機(jī)信號、非條件轉(zhuǎn)移uct、acc讀寫控制、數(shù)據(jù)存儲器讀寫控制output reg [3:0] alu_op //alu操作選擇
);initial beginstop = 0;uct = 0;acc_wr = 0;dataMem_wr = 0;alu_op = 4'b1111;endalways @(operate) begincase(operate)4'b0000: {stop,uct,acc_wr,dataMem_wr,alu_op} = 8'b00100000;   //清除累加器指令CLA4'b0001: {stop,uct,acc_wr,dataMem_wr,alu_op} = 8'b00100001;   //累加器取反指令COM    4'b0010: {stop,uct,acc_wr,dataMem_wr,alu_op} = 8'b00100010;   //算術(shù)右移一位指令SHR4'b0011: {stop,uct,acc_wr,dataMem_wr,alu_op} = 8'b00100011;   //循環(huán)左移一位指令CSL4'b0100: {stop,uct,acc_wr,dataMem_wr,alu_op} = 8'b00100100;   //加法指令A(yù)DD4'b0101: {stop,uct,acc_wr,dataMem_wr,alu_op} = 8'b00010101;   //存數(shù)指令STA4'b0110: {stop,uct,acc_wr,dataMem_wr,alu_op} = 8'b00100110;   //取數(shù)指令LDA4'b0111: {stop,uct,acc_wr,dataMem_wr,alu_op} = 8'b01000111;   //無條件轉(zhuǎn)移指令JMP4'b1000: {stop,uct,acc_wr,dataMem_wr,alu_op} = 8'b00001000;   //有條件轉(zhuǎn)移BAN4'b1001: {stop,uct,acc_wr,dataMem_wr,alu_op} = 8'b10000000;   //停機(jī)STOPendcaseendendmodule

dataMem

輸入:

dataMem_wrclkaddrdata_in
dataMem使能時鐘12位指令地址16位輸入數(shù)據(jù)

輸出:

data_out
16位輸出數(shù)據(jù)
//dataMem
module dataMem(input wire dataMem_wr, clk, //dataMem使能、時鐘input wire [11:0] addr, //12位指令地址input wire [15:0] data_in,  //16位輸入數(shù)據(jù)output wire [15:0] data_out //16位輸出數(shù)據(jù)
);reg [15:0] dataMem[4096:0]; //2^12個存儲單元,每個存儲單元16位assign data_out = dataMem[addr];initial begindataMem[0] = 16'b0000000000000001;    //初始化1dataMem[1] = 16'b0000000000000010;    //初始化2endalways@(negedge clk) beginif(dataMem_wr == 1)dataMem[addr] = data_in;endendmodule

2. CPU例化實(shí)現(xiàn)

調(diào)用以上各個模塊

module cpu(input wire clk, rst
);wire stop, ct, uct, acc_wr, dataMem_wr;wire [11:0] pc_addr;wire [3:0] alu_op;wire [15:0] ins, in1, in2, Z;//pc實(shí)例化pc pc(.clk(clk), .rst(rst), .stop(stop), .ct(ct), .uct(uct),.offset(ins[11:0]),.pc(pc_addr));//指令存儲器實(shí)例化insMem insMem(.addr(pc_addr),.Ins(ins));//acc實(shí)例化acc acc(.clk(clk), .acc_wr(acc_wr),.data_in(Z), .data_out(in1));//數(shù)據(jù)存儲器實(shí)例化dataMem dataMem(.dataMem_wr(dataMem_wr), .clk(clk),.addr(ins[11:0]),.data_in(Z),.data_out(in2));//cu實(shí)例化cu cu(.operate(ins[15:12]),.stop(stop), .uct(uct), .acc_wr(acc_wr), .dataMem_wr(dataMem_wr),.alu_op(alu_op));//alu實(shí)例化alu alu(.in1(in1), .in2(in2),.alu_op(alu_op),.ct(ct),.Z(Z));endmodule

3. 編寫測試文件

module cpu_test;reg clk, rst;initial begin clk = 1;rst = 1;#5 rst = 0;#80 $stop;endalways #5 clk = ~clk;cpu cpu(.clk(clk), .rst(rst));endmodule

4. 仿真結(jié)果及分析

根據(jù)以下原理圖及實(shí)驗結(jié)果波形圖進(jìn)行分析

1. 清除累加器指令CL


0~5ns時rst=1,pc中指令地址pc_addr=000000000000,到insMem中取出指令ins=0000000000000000,其中操作碼operation=0000傳給CU

4'b0000: {stop,uct,acc_wr,dataMem_wr,alu_op} = 8'b00100000;

CU發(fā)出以上各種控制信號

  • alu_op=0000,然后alu執(zhí)行清除累加器指令CLA,結(jié)果Z=0

    //清除累加器指令CLA
    4'b0000: Z = 0; 
    
  • dataMem_wr=0,不能對dataMem進(jìn)行寫操作;

  • acc_wr=1,可以對acc進(jìn)行寫操作

初始化時acc=1dataMem[0]=0000000000000001;因此ACC的data_out端口輸出1,傳給ALU的in1口,in1=0000000000000001;dataMem[0]的數(shù)據(jù)輸出給ACC的in2,因此in2=0000000000000001

5~10ns時:5ns時rst置0,時鐘下降沿;ALU將Z=0寫入ACC中,同時ACC輸出數(shù)據(jù)到in1,使得in1=000000000000in2不變


2. 累加器取反指令COM


10ns~15ns時:10ns時鐘上升沿,pc_addr加1得pc_addr=000000000001,到insMem中取出指令ins=0001000000000000,其中的操作碼operation=0001傳給CU

4'b0001: {stop,uct,acc_wr,dataMem_wr,alu_op} = 8'b00100001;

CU發(fā)出以上各種控制信號

  • alu_op=0001:alu執(zhí)行清除累加器指令CLA,結(jié)果Z=~in1=111111111111

    //累加器取反指令COM 
    4'b0001: Z = ~in1;      
    
  • dataMem_wr=0,不能對dataMem進(jìn)行寫操作

  • acc_wr=1,可以對acc進(jìn)行寫操作

此時in1in2均不變

15~20ns時:15ns時鐘下降沿,ALU將Z=111111111111寫入ACC中,同時ACC輸出數(shù)據(jù)到in1,使得in1=111111111111


3. 算術(shù)右移一位指令SHR

20ns~25ns時:20ns時鐘上升沿,pc_addr加1得pc_addr=000000000010,到insMem中取出指令ins=0010000000000000,其中的操作碼operation=0010傳給CU

4'b0010: {stop,uct,acc_wr,dataMem_wr,alu_op} = 8'b00100010;

CU發(fā)出以上各種控制信號

  • alu_op=0010,然后alu執(zhí)行算術(shù)右移一位指令SHR,結(jié)果Z=111111111111

    //算術(shù)右移一位指令SHR
    4'b0010: Z = in1[15] == 1 ? {1'b1, in1[15:1]} : {1'b0, in1[15:1]}; 
    
  • dataMem_wr=0,不能對dataMem進(jìn)行寫操作;acc_wr=1,可以對acc進(jìn)行寫操作

in2不變

25~30ns時:25ns時鐘下降沿,ALU將Z=111111111111寫入ACC中,同時ACC輸出數(shù)據(jù),使得in1=111111111111in2不變


4. 循環(huán)左移一位指令CSL

30ns~35ns時:30ns時鐘上升沿,pc_addr加1得pc_addr=00000011,到insMem中取出指令ins=0011000000000000,其中的操作碼operation=0011傳給CU

4'b0011: {stop,uct,acc_wr,dataMem_wr,alu_op} = 8'b00100011; 

CU發(fā)出以上各種控制信號

  • alu_op=0011,alu執(zhí)行循環(huán)左移一位指令CSL,結(jié)果Z=111111111111

    //循環(huán)左移一位指令
    CSL4'b0011: Z = {in1[14:0], in1[15]};    
    
  • dataMem_wr=0,不能對dataMem進(jìn)行寫操作;acc_wr=1,可以對acc進(jìn)行寫操作

in2不變

35~40ns時:35ns時鐘下降沿,ALU將Z=111111111111寫入ACC中,同時ACC輸出數(shù)據(jù),使得in1=111111111111in2不變


5. 加法指令A(yù)DD

40ns~45ns時:40ns時鐘上升沿,pc_addr加1得pc_addr=00000100,到insMem中取出指令ins=0100000000000001,其中的操作碼operation=0100傳給CU

4'b0100: {stop,uct,acc_wr,dataMem_wr,alu_op} = 8'b00100100;

CU發(fā)出以上各種控制信號

  • alu_op=0100,然后alu執(zhí)行加法指令A(yù)DD,in2從dataMem[1]讀入數(shù)據(jù),與ACC的數(shù)據(jù)相加得結(jié)果Z=1111111111111111+b0000000000000010=0000000000000001

    //加法指令A(yù)DD
    4'b0100: Z = in1 + in2;
    
  • dataMem_wr=0,不能對dataMem進(jìn)行寫操作;

  • acc_wr=1,可以對acc進(jìn)行寫操作

45~50ns時:45ns時鐘下降沿,ALU將Z=0000000000000001寫入ACC中,同時ACC輸出數(shù)據(jù),使得in1=0000000000000001in2不變;Z=in1+in2=0000000000000011


6. 存數(shù)指令STA

50ns~55ns時:50ns時鐘上升沿,pc_addr加1得pc_addr=000000000101,到insMem中取出指令ins=0101000000000000,其中的操作碼operation=0101傳給CU

4'b0101: {stop,uct,acc_wr,dataMem_wr,alu_op} = 8'b00010101;

CU發(fā)出以上各種控制信號

  • alu_op=0101,然后alu執(zhí)行存數(shù)指令STA,結(jié)果Z=in1=0000000000000001

    //存數(shù)指令STA
    4'b0101: Z = in1; 
    
  • dataMem_wr=1,可以對dataMem進(jìn)行寫操作

  • acc_wr=0,不能對acc進(jìn)行寫操作

55~60ns時:55ns時鐘下降沿,ALU將Z=0000000000000001寫入dataMem[000000000101]中,輸出數(shù)據(jù),使得in2=0000000000000001in1不變


7. 取數(shù)指令LDA


60ns~65ns時:60ns時鐘上升沿,pc_addr加1得pc_addr=00000110,到insMem中取出指令ins=0110000000000000,其中的操作碼operation=0110傳給CU

4'b0110: {stop,uct,acc_wr,dataMem_wr,alu_op} = 8'b00100110;

CU發(fā)出以上各種控制信號

  • alu_op=0110,然后alu執(zhí)行取數(shù)指令LDA,結(jié)果Z=in2=0000000000000001

  • dataMem_wr=0,不能對dataMem進(jìn)行寫操作;acc_wr=1,可以對acc進(jìn)行寫操作

65~70ns時:65ns時鐘下降沿,ALU將Z=0000000000000001寫入ACC中,同時輸出數(shù)據(jù),使得in1=0000000000000001in2不變


8. 無條件轉(zhuǎn)移指令JMP


70ns~75ns時:70ns時鐘上升沿,pc_addr加1得pc_addr=000000000111,到insMem中取出指令ins=0111000000001001,其中的操作碼operation=0111傳給CU

4'b0111: {stop,uct,acc_wr,dataMem_wr,alu_op} = 8'b00000111;

CU發(fā)出以上各種控制信號

  • alu_op=0111,然后alu執(zhí)行無條件轉(zhuǎn)移指令JMP
  • dataMem_wr=0,不能對dataMem進(jìn)行寫操作;acc_wr=0,不能對acc進(jìn)行寫操作
  • uct=1,進(jìn)行無條件轉(zhuǎn)移

75~80ns時:75ns時鐘下降沿,pc被修改,轉(zhuǎn)移偏移量為9,pc_addr=000000001001-1=000000001000


9. 有條件轉(zhuǎn)移指令BAN


80ns~85ns時:80ns時鐘上升沿,pc_addr加1得pc_addr=00001001,到insMem中取出指令ins=1000000000001001,其中的操作碼operation=1000傳給CU

4'b1000: {stop,uct,acc_wr,dataMem_wr,alu_op} = 8'b00001000;

CU發(fā)出以上各種控制信號

  • alu_op=1001,然后alu執(zhí)行有條件轉(zhuǎn)移指令BAN,結(jié)果ct=0

    //有條件轉(zhuǎn)移BAN
    4'b1000: ct = in1[15]==1?1:0;
    
  • dataMem_wr=0,不能對dataMem進(jìn)行寫操作;

  • acc_wr=0,不能對acc進(jìn)行寫操作

85~90ns時:75ns時鐘下降沿,由于ct,所以pc不被修改,保持不變


10. 停機(jī)指令STP

90ns后:90ns時鐘上升沿,pc_addr加1得pc_addr=00001001,到insMem中取出指令ins=100100000000000,其中的操作碼operation=1001傳給CU

4'b1001: {stop,uct,ct,acc_wr,dataMem_wr,alu_op} = 8'b100000000;   

CU使stop=1,發(fā)出停機(jī)控制信號,執(zhí)行停機(jī)指令

//停機(jī)指令STP 
4'b1001: ;

從此pc不再增加,保持不變

總結(jié)

以上是生活随笔為你收集整理的单周期十条指令CPU设计与verilog实现(Modelsim)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。