【計算機系統設計】實踐筆記(3)改進數據通路:移位R型指令分析

0 回顧

前面的內容中,第一類R型指令分析,我們完成了一類R型指令的設計,完成了其數據通路,構建了相應的部件,并且完成了從ROM中取指,成功進行了基本的功能仿真,進行了綜合和實現,但是沒有完成綜合和實現的時序仿真。

下面,我們要繼續進行其他R型指令的分析,這次我們只分析三個移位指令,也就是sll srl sra,然后改進我們已有的數據通路,完成對應的設計。

1 移位指令分析

我們先看看指令編碼

instructionoprsrtrdshamtfunc
sll00000000000rtrdshamt000000
srl00000000000rtrdshamt000010
sra00000000000rtrdshamt000011

再看看其功能邏輯

三個指令的邏輯都是一樣的

  • rd <- (rt op shamt)
  • op:
    • srl: >>
    • sll: <<
    • sra: >>>

指令的使用:instruction rd,rs,shamt

值得注意的是,shamt是5位,范圍是0~31.

需要的器件和信號

我們依次分析一下,完成操作,需要改進哪些部件和信號

很容易知道,我們只需要改進一下ALU的輸入數據和控制即可,同時控制器要識別出這三個指令,增加一些相關信號。

  1. ALU
    1. 增加shamt的輸入
    2. 移位操作不需要增加,之前已經實現過
    3. 移位操作的輸入需要增加選擇,使得rt和shamt被正確輸入
    4. 為ALU增加控制信號Sftmd,表明是這幾個移位操作
  2. 控制器:增加控制信號Sftmd輸出到ALU

我們原來的數據通路就變成了
在這里插入圖片描述

3 ALU和控制器設計改進

3.1 控制器設計

我們把之前的也拿出來,同時標出新增內容。

  • 輸入信號:op func
  • 輸出信號:RegWrite ALUop新增Sftmd
instructionopfuncALUopRegWriteSftmd 新增
add000000100000000010
addu000000100001000110
sub000000100010001010
subu000000100011001110
and000000100100010010
or000000100101010110
xor000000100110011010
nor000000100111011110
slt000000101010100010
sltu000000101011100110
sllv000000101010101010
srlv000000000110101110
srav000000000111110010
新增
sll000000000000101011
srl000000000010101111
sra000000000011110011

3.2 ALU設計

  • 數據輸入:R[rs] R[rd]新增shamt
  • 控制輸入:ALUop新增Sftmd
  • 數據輸出:R[rd]

特別的,當Sftmd == 1(表明是移位指令)的時候,ALU增加了多路選擇器,將sllv等指令的輸入由rtrs變成了rtshamt

也就是在rsshamt之間增加了選擇器,當Shtmd == 1使用shamt作為輸入,注意需要0擴展為32位進行運算。

注意:改了輸入輸出端口,相應的實例也要改。

4 Verilog實現

我們下面改進代碼!

4.1 Bug修復:sllv等指令的ALU錯誤

設計中發現,之前的設計有錯誤!是在移位指令的時候!我們先來改正它,并且改進我們的測試實例。

sllv舉例,它是使用方法是sllv rd,rt,rs,邏輯是rd <- rt << rs

匯編程序員視角

是正常指令的使用,邏輯也是正常的,但是,內部邏輯卻不一樣了。

內部邏輯

例如sllv $5,$10,$9,功能操作是$5 = $10 << $9,而內部是

  • rt = $10 對應ALU的B
  • rs = $9 對應ALU的A
  • ALU操作是B << A,而不是A << B

這里之前犯的錯誤是,改變了程序員視角的指令……,將上層和底層搞混了……

4.2 新的ALU

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/11/14 22:30:23
// Design Name:
// Module Name: ALU_1
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module ALU_1(// datainput [31:0] A,input [31:0] B,input [4:0] shamt,// controlinput [3:0] ALUop,input Sftmd, // shift instruction controloutput reg [31:0] ALUresult);// convert A and B to signed numbers
wire signed [31:0] A_signed = A;
wire signed [31:0] B_signed = B;// for shift instructions
// select data: if (Sftmd == 1) input shamt else input rs
wire [31:0] A_or_Shift = (Sftmd == 0) ? A : {27'b0,shamt};/* calculate */
always @(*)
begincase (ALUop)4'b0000:    // addbeginALUresult <= A + B;end4'b0001:    // addubeginALUresult <= A + B;end4'b0010:    // subbeginALUresult <= A - B;end4'b0011:    // sububeginALUresult <= A - B;end4'b0100:    // andbeginALUresult <= A & B;end4'b0101:    // orbeginALUresult <= A | B;end4'b0110:    // xorbeginALUresult <= A ^ B;end4'b0111:    // norbeginALUresult <= ~(A | B);end4'b1000:    // slt // note:********signed********//beginif(A_signed < B_signed)ALUresult <= 1;elseALUresult <= 0;end4'b1001:    // sltubeginif(A < B)ALUresult <= 1;elseALUresult <= 0;end4'b1010:    // sllv 10beginALUresult <= B << A_or_Shift;    // NOTE: not A << B!end4'b1011:    // srlvbeginALUresult <= B >> A_or_Shift;    // NOTE: not A >> B!end4'b1100:    // srav // note: ******signed*******//beginALUresult <= B_signed >>> A_or_Shift;    // NOTE: not A_signed >> B!enddefault:beginALUresult <= 0;endendcase
endendmodule

關注移位指令的部分即可,同時注意最開始的多路選擇器。

4.3 新的control

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/11/14 22:30:48
// Design Name:
// Module Name: control_1
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module control_1(input [5:0] op,input [5:0] func,output reg RegWrite,output reg Sftmd,    // indicate the instruction is sll/srl/sraoutput reg [3:0] ALUop);always @(*)
beginif(op == 6'b0)begincase (func)6'b100000:  // addbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b0000;end6'b100001:  // addubeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b0001;end6'b100010:  // subbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b0010;end6'b100011:  // sububeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b0011;end6'b100100:  // andbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b0100;end6'b100101:  // orbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b0101;end6'b100110:  // xorbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b0110;end6'b100111:  // norbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b0111;end6'b101010:  // sltbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b1000;end6'b101011:  // sltubeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b1001;end6'b000100:  // sllvbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b1010;end6'b000110:  // srlvbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b1011;end6'b000111:  // sravbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b1100;end6'b000000:  // sllbeginRegWrite <= 1;Sftmd <= 1;ALUop <= 4'b1010;end6'b000010:  // srlbeginRegWrite <= 1;Sftmd <= 1;ALUop <= 4'b1011;end6'b000011:  // srabeginRegWrite <= 1;Sftmd <= 1;ALUop <= 4'b1100;enddefault:beginRegWrite <= 0;Sftmd <= 0;ALUop <= 4'b1111;endendcaseendelsebeginRegWrite <= 0;Sftmd <= 0;ALUop <= 4'b1111;end
endendmodule

注意新增的信號。

4.4 新的datapath

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/11/27 11:41:34
// Design Name:
// Module Name: datapath_1
// Project Name:
// Target Devices:
// Tool Versions:
// Description: 僅僅實現了幾個簡單的R類指令的最簡單的數據通路,不與外界交互
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module datapath_1(input clk,input rst_n,output [31:0] result // 測試syntheses,沒有輸出的模塊是恐怖的);/******** PC ********/// pc_1 Outputs
wire  [31:0]  pcOld;pc_1  u_pc_1 (.clk                     ( clk     ),.rst_n                   ( rst_n   ),.pcNew                   ( pcOld   ), // pcNew = pcOld + 4; no selection.pcOld                   ( pcOld   ));/******** Instruction ROM ********/// blk_mem_gen_0 Inputs
// wire  [13:0]  addra  = pcOld[15:2];// blk_mem_gen_0 Outputs // instructions
wire  [31:0]  instruction;blk_mem_gen_0  u_blk_mem_gen_0 (.clka                    ( clk    ),.addra                   ( pcOld[15:2]   ),.douta                   ( instruction   ));/******** Reg Files ********/// reg_files_1 Inputs
wire  [31:0]  ALUresult;/// wire   [4:0]  rA = instruction[25:21];
/// wire   [4:0]  rB = instruction[20:16];
/// wire   [4:0]  rW = instruction[15:11];
/// wire   [31:0]  writeData = ALUresult;
wire   RegWrite;// reg_files_1 Outputs
wire  [31:0]  A;
wire  [31:0]  B;reg_files_1  u_reg_files_1 (.clk                     ( clk         ),.rst_n                   ( rst_n       ),.rA                      ( instruction[25:21]          ),.rB                      ( instruction[20:16]          ),.rW                      ( instruction[15:11]          ),.writeData               ( ALUresult   ),.RegWrite                ( RegWrite    ),.A                       ( A           ),.B                       ( B           ));/******** ALU ********/// ALU_1 Inputs
// wire   [31:0]  A;
// wire   [31:0]  B;
wire   [3:0]  ALUop;
wire   Sftmd;// ALU_1 OutputsALU_1  u_ALU_1 (.A                       ( A           ),.B                       ( B           ),.shamt                   ( instruction[10:6]),.ALUop                   ( ALUop       ),.Sftmd                   ( Sftmd       ),.ALUresult               ( ALUresult   ));/******** controler ********/// control_1 Inputs
// wire   [5:0]  op = instruction[31:26];
// wire   [5:0]  func = instruction[5:0];// control_1 Outputs
// wire  RegWrite
// wire  [3:0]  ALUop;control_1  u_control_1 (.op                      ( instruction[31:26]         ),.func                    ( instruction[5:0]       ),.RegWrite                ( RegWrite   ),.Sftmd                   ( Sftmd      ),.ALUop                   ( ALUop      ));assign result = ALUresult;endmodule

注意實例化的時候,信號不要弄錯。

4.5 舊的測試:tb_datapath

激勵塊內容不變。

4.6 新的測試用例

nop
add $1,$2,$3	# $1 = 2 + 3 = 5
addu $2,$4,$1	# $2 = 4 + 5 = 9
sub $4,$2,$1	# $4 = 9 - 5 = 4
subu $5,$4,$3	# $5 = 4 - 3 = 1and $6,$7,$8	# $6 = 0111 and 1000 = 0
or $7,$6,$8		# $7 = 0 or 1000 = 8
xor $7,$6,$8	# $7 = 0000 xor 1000 = 1000 = 8
nor $8,$7,$6	# $8 = not (1000 or 0) = 11111111111110111slt $10,$11,$12	# $10 = 11 < 12 = 1		# 應該用負數驗證,以后再說
sltu $10,$12,$11	# $10 = 12 > 11 = 0# sllv $12,$5,$13	# $12 = 1101 << 1 = 1101_0 = 1A	【注意此處的倒置問題! sllv rd,rt,rs】
# srlv $12,$5,$13	# $12 = 1101 >> 1 = 110 = 6
# srav $14,$5,$15	# $14 = 1111 >>> 1 = 111  = 7 應該用負數驗證,以后再說# 上面3條是錯誤的!我們應該改的不是使用,而是內部運算邏輯
# 對于使用者來說,邏輯就是 $13 << $5
# 而實際的編碼是 rt = $13,rs = $5,這與一般的指令不一樣
# 因此,我們在ALU運算中 rt--B,rs--A,應該是 【B << A】,而不是 A >> B。
sllv $12,$13,$5	# $12 = 1101 << 1 = 1101_0 = 1A	
srlv $12,$13,$5	# $12 = 1101 >> 1 = 110 = 6
srav $14,$15,$5	# $14 = 1111 >>> 1 = 111  = 7 應該用負數驗證,以后再說sll $16,$17,2	# $16 = 1_0001 << 2 = 100_0100 = 44	
srl $16,$18,2	# $16 = 1_0010 >> 2 = 0100 = 4
sra $16,$19,2	# 應該用負數驗證,以后再說 $16 = 4

特別注意最后移位指令,注意注釋內容。

指令編碼的coe文件:

memory_initialization_radix = 16;
memory_initialization_vector =
00000000,
00430820,
00811021,
00412022,
00832823,
00e83024,
00c83825,
00c83826,
00e64027,
016c502a,
018b502b,
00ad6004,
00ad6006,
00af7007,
00118080,
00128082,
00138083;

最終測試

經過了每個模塊的RTL優化和最終的仿真測試,結果沒有問題!我們又為之前的數據通路增加了新的3個指令!Fighting!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/384643.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/384643.shtml
英文地址,請注明出處:http://en.pswp.cn/news/384643.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【計算機系統設計】實踐筆記(3)改進數據通路:jr指令分析與實現

1 jr指令分析 instructionoprsrtrdshamtfuncjr000000rs000000000000000001000 舉例&#xff1a;jr $31 功能&#xff1a;PC <- &#xff08;$31&#xff09; 這是個跳轉指令&#xff0c;將指定寄存器的值&#xff0c;放入PC中&#xff0c;是無條件跳轉。 我們需要 更新P…

【計算機系統設計】實踐筆記(4)改進數據通路:第一類I型指令分析與實現

0 回顧 之前&#xff0c;我們完成了17條R型指令的設計&#xff0c;接下來&#xff0c;我們逐步完成I型指令的設計。 1 核心思想&#xff1a;增量思維 & 復用思維 & 學會選擇 & 分治思想 增量思維 我們從無到有&#xff0c;構建了支持R型指令的CPU&#xff0c;接…

【算法】學習筆記(1):算法就是人類去教會計算機的方法

人生處處皆算法&#xff0c;算法是解決問題之道。 對于計算機科學中的算法&#xff0c;我更喜歡將其理解為利用人類思維之一&#xff1a;計算機思維&#xff0c;去解決一些人類不擅長的問題&#xff0c;比如大量重復運算&#xff0c;然后&#xff0c;人類使用計算機編程語言去…

【算法】學習筆記(2):遞歸思想

0 回顧 之前的筆記&#xff08;0&#xff09;和筆記&#xff08;1&#xff09;&#xff0c;我們介紹了算法的基本含義&#xff0c;并且舉了一些實例&#xff0c;同時理解了&#xff0c;算法就是人類在教計算機做事情&#xff01; 我們知道&#xff0c;算法就是解決問題的方案…

【計算機系統設計】實踐筆記(5)插敘:內外有別之CPU和Memory

區分CPU的內外 首先明確&#xff0c;內存&#xff0c;不在CPU內&#xff0c;我們的CPU是會有數據和指令端口的&#xff0c;然后去訪問內存和外設。 而CPU設計&#xff0c;我們所說的單周期&#xff0c;多周期和流水線&#xff0c;描述的都是CPU&#xff0c;而不是Memory&…

【計算機系統設計】實踐筆記(5)改進數據通路:beq和bne指令分析與實現

接下來的分析和實踐非常粗糙&#xff0c;因為跟之前一樣的分析流程&#xff0c;不再多說了&#xff0c;如果前面真的掌握&#xff0c;這里不看也罷。 分析 先看beq指令。 ALU輸入的是rs和rt&#xff0c;不輸入imm&#xff0c;進行subu操作&#xff0c;判斷是否為zero&#x…

【算法】學習筆記(4):分治思想 歸并排序

分治思想&#xff0c;分治策略&#xff0c;自古有之&#xff0c;與人類生活息息相關&#xff0c;其本質是將大問題拆解為小問題&#xff0c;小問題轉換為已知解的問題&#xff0c;進而求解。 軍隊管理&#xff0c;國家分級治理…… 大規模數據排序&#xff0c;例如10000000000…

【算法】學習筆記(5):快速排序

注意一個C的坑 sizeof()這個函數靜態數組可以求長度&#xff0c;動態new出來的數組不行&#xff0c;因為針對的是指針……&#xff0c;不過既然的動態數組了&#xff0c;其長度本身必然是一個變量了&#xff0c;你沒有必要這么求長度。 下面看快速排序的代碼。 #include <…

【計算機系統設計】實踐筆記(6)改進數據通路:lw和sw指令

不想多說了……前面的鋪墊足夠了&#xff0c;剩下的自己做做應該也會了&#xff0c;如果遇到問題&#xff0c;就搜一下自己查閱就好。 這篇水過&#xff0c;沒有太多技術點。 唯一注意的是&#xff0c;引入的RAM和ROM的clk觸發問題&#xff0c;可能引起時序問題&#xff0c;等…

html css 核心設計理念

分開看&#xff01; 從不同視角&#xff0c;獨立地去看某一部分內容&#xff0c;使用聚焦視角&#xff0c;進行獨立操作和批量操作。

html css 學習筆記(1)背景相關

背景顏色 圖片 插入圖片img背景圖片 背景圖片 3. logo 4. 大圖 5. 裝飾性小圖 便于控制位置&#xff01; 插入后會執行自動平鋪&#xff0c;這與插入圖片是不同的&#xff01; div{width: 600px;height: 300px;background-image: url(img/登錄用戶頭像.png); }小結 盒子的第…

html css a標簽的應用

作為普通鏈接轉換為行內塊元素 轉換為行內塊元素之后&#xff0c;就可以給其各種塊行為&#xff0c;加背景&#xff0c;加背景圖片&#xff0c;設置寬高&#xff0c;內外邊距…… 塊行為可以的&#xff0c;它都行&#xff0c;唯一的區別&#xff0c;它這個盒子是個鏈接&#…

GitHub回滾

不要直接退回到很久前的歷史版本&#xff0c;這很可能引起文件沖突&#xff0c;可以一步步回滾&#xff0c;先回滾最近的&#xff0c;從近到遠一步步滾到目標。

2020-12-15 CPU設計復盤

SOC修改 將之前完成的31條指令單周期CPU進行了重構&#xff0c;將其分開&#xff0c;實現了內外有別&#xff0c;將CPU、指令ROM和數據RAM。 這樣&#xff0c;以后為其增加接口外設&#xff0c;總線控制&#xff0c;才更加清晰&#xff0c;這是進一步封裝和抽象。 MARS大坑 …

Tomcat 學習筆記(0)

JavaWeb 用Java寫的程序&#xff0c;可以在瀏覽器運行。 Request & Responce Web資源 Web服務器 我們在自己的主機啟動Tomcat服務器&#xff0c;然后運行它&#xff0c;就能夠通過主機訪問這個服務器&#xff0c;這個服務器能夠運行我們的程序。 部署Web工程 法1 將web…

計算機系統 學習筆記(0)南京大學(一)第一周

課程&#xff1a;計算機系統基礎 核心理念&#xff1a;人類世界與計算機世界的異同 人類世界 直觀感受數學 計算機世界 與數學不同&#xff0c;存儲首先&#xff0c;各層次與現實世界不同 我們關注點是差異點&#xff01; 一樣的你就不用關心了&#xff0c;關心差異&#…

x86架構下 CF與OF標志位 帶符號和無符號運算 詳解

針對能夠影響OF和CF標志位的指令&#xff0c;一般來說是涉及到數據運算的指令&#xff0c;這里使用add舉例&#xff0c;即不區分有無符號的加法指令&#xff0c;參與運算的數據&#xff0c;從二進制層級去考慮。 CF標志位 對于CF&#xff0c;它是carry flag&#xff0c;進位標…

tmux學習筆記

參考學習鏈接 我們需要理解幾個重要的概念 session 回話window 窗口pane 窗格 window 我們打開的一個terminal就是一個window. 而打開的這個window&#xff0c;也就是打開了一個session&#xff0c;打開window&#xff0c;session開始&#xff1b;關閉window&#xff0c;se…

安裝win10和Linux雙系統的個人經驗

使用easy uefi誤刪除win10引導文件 這個時候&#xff0c;網上教程有各種方式&#xff0c;我直接使用了一種最簡單的&#xff0c;這個方法網上都沒有提到過。 注意&#xff1a;發現引導文件刪了&#xff0c;千萬不要關機&#xff0c;否則再想開機恐怕只能重裝系統了。 我們直…

Linux的ext4文件系統學習筆記

補充&#xff1a;設備獨立性 Linux中&#xff0c;設備驅動以文件形式表示&#xff0c;用戶操作邏輯設備就是操作文件&#xff0c;而不是具體的物理設備&#xff0c;也就是說&#xff0c;用戶操作的是功能&#xff0c;是黑箱&#xff0c;而不是真正的實體。 APP操作的都是邏輯…