【计算机系统设计】实践笔记(5)改进数据通路:beq和bne指令分析与实现

接下来的分析和实践非常粗糙,因为跟之前一样的分析流程,不再多说了,如果前面真的掌握,这里不看也罢。

分析

先看beq指令。

ALU输入的是rs和rt,不输入imm,进行subu操作,判断是否为zero,输出zero信号。

控制器增加Branch信号,识别beq指令,当zero和Branch同时成立,就可以跳转,目标地址是PC + 4 + (sign-extend)offset。

bne指令同理。

实现

ALU

ALU增加zero输出,如果rs - rt == 0zero = 0,即rs = rt,对应beq指令,若zero = 1,对应bne指令

增加offset输出,是offset字段符号扩展并左移2位后的结果,用于和pc + 4在pc模块相加。

pc

增加offset数据信号,以及Branch和nBranch跳转信号,和zero信号。

control

增加BranchnBranch信号。

Datapath

最后更改顶层数据通路。

注意一个大坑

我们设计的数据通路,取指需要2个周期,这个时候,跳转指令的pc,其实已经变成了pc + 8了,如果再执行 pc + 4 + offset,就会执行原本应该执行的下下条指令,这是错误的

因此,我们应该将PC + 4的值,与当前执行的PC指令,一起传过去。这里偷懒起见,直接在原来基础上PC - 8以避开2个时钟周期的取指延迟。

关于取指延迟对需要pc值的指令的影响,可能有不少,后续再说

在这里插入图片描述
可以看见,ROM延迟两个时钟周期,因此说,刚才的解决方案,也不对……即便能够跳转到正确的指令,但是,在此之前,如果有指令不需要执行,但是也被执行了,每一个b跳转指令,最多被错误地执行2条指令

……这可咋办呢?这是单周期,又不是流水线……如何改变局面?

后续再说。

类比:这个情况下,似乎是类流水线了,分为取指和执行2个阶段!……嗯,回头想想解决方案吧

尝试一

取指占2个时钟周期,执行占1个时钟周期,每条指令执行占3个时钟周期。

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/11/12 20:31:59
// Design Name:
// Module Name: pc_1
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module pc_1(input clk,input rst_n,// pc datainput [31:0] pcOrigin,  // The PC value is from pcOld.input [31:0] JrPC,   // jr instruction,from reg files.// pc controlinput Jrn,   // jr instruction.// beq bneinput [31:0] offset,input zero,input Branch,input nBranch,output [31:0] pcOld);reg [31:0] pc = 0;
assign pcOld = pc;// judge validity of beq/bne instruction
reg isBranch;
always @(*)
beginif((zero == 1) && (Branch == 1)) // beq validbeginisBranch <= 1;endelse if((zero == 0) && (nBranch == 1)) // bne validbeginisBranch <= 1;endelsebeginisBranch <= 0;end
end// select new pc value
reg [31:0] pcSelect; // new pc data
always @(*)
begincase({Jrn,Branch,nBranch})3'b000: // pc + 4pcSelect <= pcOrigin + 4;3'b100: // jrpcSelect <= JrPC;3'b010: // beqpcSelect <= pcOrigin + 4 + offset;  /**** NOTE ****/3'b001: // bne // fetch instruction waste 2 clock cycles,then execute 1 cyclepcSelect <= pcOrigin + 4 + offset;  /**** NOTE ****/default:pcSelect <= 0;endcase
end// counter: wait 2 clock cycles to fetch instruction
reg counter = 0;
always @(posedge clk)
beginif(counter == 1)counter <= 0;elsecounter <= counter + 1;
end// Update PC register
always @(posedge clk)
beginif(rst_n == 1) // Xilinx 官方推荐:reset 高电平有效beginpc <= 0;endelse if(counter == 1)beginpc <= pcSelect;endelsebeginpc <= 0;end
endendmodule

加了计时器,但是,还是解决不了问题……

在这里插入图片描述

现在,能够满足当前执行的指令,pc值是下一条指令的地址,但是更新存在问题,依然避不开的是,取指需要2个时钟周期

问题解决:让CPU与Memory的时钟频率不一样!

首先,我们需要知道,CPU和Memory内外有别,它们的clk频率完全可以不一样,这样,我们让Memory的频率快一点,使得CPU在一个时钟周期内,完成取指和执行,就满足了我们的设计要求。

这里需要强化一个概念,我们需要知道,单周期CPU,指的是CPU在一个时钟周期内能够完成一条指令的取指和执行操作单周期指的是CPU,而不是Memory。

实践笔记(5)插叙:内外有别之CPU和Memory

1 解决方案

1.1 增加时钟分频器

在这里插入图片描述在这里插入图片描述
使用MMCM,不是PLL

在这里插入图片描述
在这里插入图片描述
注意,此IP核有启动时间。

在这里插入图片描述
另外……当仿真没有信号的时候,看看是不是没有加信号……
在这里插入图片描述

1.2 分别对待CPU与Memory的时钟频率

CPU时钟频率20MHz
内存时钟频率100MHz

1.3 其他部件的实现

PC

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/11/12 20:31:59
// Design Name:
// Module Name: pc_1
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module pc_1(input clk,input rst_n,// pc datainput [31:0] pcOrigin,  // The PC value is from pcOld.input [31:0] JrPC,   // jr instruction,from reg files.// pc controlinput Jrn,   // jr instruction.// beq bneinput [31:0] offset,input zero,input Branch,input nBranch,output [31:0] pcOld);reg [31:0] pc = 0;
assign pcOld = pc;// judge validity of beq/bne instruction
reg isBranch;
always @(*)
beginif((zero == 1) && (Branch == 1)) // beq validbeginisBranch <= 1;endelse if((zero == 0) && (nBranch == 1)) // bne validbeginisBranch <= 1;endelsebeginisBranch <= 0;end
end// select new pc value
reg [31:0] pcSelect; // new pc data
always @(*)
begincase({Jrn,isBranch})2'b00: // pc + 4pcSelect <= pcOrigin + 4;2'b10: // jrpcSelect <= JrPC;// fetching 1 instruction wastes 2 clock cycles(memory), and// executing the instruction needs 1 clock cycle(CPU).// NOTE:the frequency of two clocks is different. 2'b01: // beq bnepcSelect <= pcOrigin + 4 + offset;    default:pcSelect <= 0;endcase
end// Update PC register
always @(posedge clk)
beginif(rst_n == 1) // Xilinx suggest:reset high level effectivebeginpc <= 0;endelsebeginpc <= pcSelect;end
endendmodule

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,output reg Jrn,   // jr instructionoutput reg Lui,   // lui instructionoutput reg RegDst,output reg ALUSrc,output reg Zero_sign_ex,output reg Branch,   // beqoutput reg nBranch   // bne);always @(*)
begincase(op)6'b000000:   R-type begincase (func)6'b100000:  // addbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b0000;Jrn <= 0;Lui <= 0;RegDst <= 1;ALUSrc <= 0;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b100001:  // addubeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b0001;Jrn <= 0;Lui <= 0;RegDst <= 1;ALUSrc <= 0;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b100010:  // subbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b0010;Jrn <= 0;Lui <= 0;RegDst <= 1;ALUSrc <= 0;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b100011:  // sububeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b0011;Jrn <= 0;Lui <= 0;RegDst <= 1;ALUSrc <= 0;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b100100:  // andbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b0100;Jrn <= 0;Lui <= 0;RegDst <= 1;ALUSrc <= 0;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b100101:  // orbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b0101;Jrn <= 0;Lui <= 0;RegDst <= 1;ALUSrc <= 0;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b100110:  // xorbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b0110;Jrn <= 0;Lui <= 0;RegDst <= 1;ALUSrc <= 0;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b100111:  // norbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b0111;Jrn <= 0;Lui <= 0;RegDst <= 1;ALUSrc <= 0;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b101010:  // sltbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b1000;Jrn <= 0;Lui <= 0;RegDst <= 1;ALUSrc <= 0;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b101011:  // sltubeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b1001;Jrn <= 0;Lui <= 0;RegDst <= 1;ALUSrc <= 0;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b000100:  // sllvbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b1010;Jrn <= 0;Lui <= 0;RegDst <= 1;ALUSrc <= 0;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b000110:  // srlvbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b1011;Jrn <= 0;Lui <= 0;RegDst <= 1;ALUSrc <= 0;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b000111:  // sravbeginRegWrite <= 1;Sftmd <= 0;ALUop <= 4'b1100;Jrn <= 0;Lui <= 0;RegDst <= 1;ALUSrc <= 0;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b000000:  // sllbeginRegWrite <= 1;Sftmd <= 1;ALUop <= 4'b1010;Jrn <= 0;Lui <= 0;RegDst <= 1;ALUSrc <= 0;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b000010:  // srlbeginRegWrite <= 1;Sftmd <= 1;ALUop <= 4'b1011;Jrn <= 0;Lui <= 0;RegDst <= 1;ALUSrc <= 0;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b000011:  // srabeginRegWrite <= 1;Sftmd <= 1;ALUop <= 4'b1100;Jrn <= 0;Lui <= 0;RegDst <= 1;ALUSrc <= 0;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b001000:  // jrbeginRegWrite <= 0;Sftmd <= 0;ALUop <= 4'b1111;Jrn <= 1;Lui <= 0;RegDst <= 1;ALUSrc <= 0;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;enddefault:beginRegWrite <= 0;Sftmd <= 0;ALUop <= 4'b1111;Jrn <= 0;Lui <= 0;RegDst <= 1;ALUSrc <= 0;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;endendcaseend/*************** I-type ***************/6'b001000:  // addibeginALUop <= 4'b0000;RegWrite <= 1;Sftmd <= 0;Jrn <= 0;Lui <= 0;RegDst <= 0;ALUSrc <= 1;Zero_sign_ex <= 1;Branch <= 0;nBranch <= 0;end6'b001001:  // addiubeginALUop <= 4'b0001;RegWrite <= 1;Sftmd <= 0;Jrn <= 0;Lui <= 0;RegDst <= 0;ALUSrc <= 1;Zero_sign_ex <= 1;Branch <= 0;nBranch <= 0;end6'b001100:  // andibeginALUop <= 4'b0100;RegWrite <= 1;Sftmd <= 0;Jrn <= 0;Lui <= 0;RegDst <= 0;ALUSrc <= 1;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b001101:  // oribeginALUop <= 4'b0101;RegWrite <= 1;Sftmd <= 0;Jrn <= 0;Lui <= 0;RegDst <= 0;ALUSrc <= 1;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b001110:  // xoribeginALUop <= 4'b0110;RegWrite <= 1;Sftmd <= 0;Jrn <= 0;Lui <= 0;RegDst <= 0;ALUSrc <= 1;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b001111:  // lui  note beginALUop <= 4'b1101;RegWrite <= 1;Sftmd <= 0;Jrn <= 0;Lui <= 1;RegDst <= 0;ALUSrc <= 1;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b001010:  // sltibeginALUop <= 4'b1000;RegWrite <= 1;Sftmd <= 0;Jrn <= 0;Lui <= 0;RegDst <= 0;ALUSrc <= 1;Zero_sign_ex <= 1;Branch <= 0;nBranch <= 0;end6'b001011:  // sltiubeginALUop <= 4'b1001;RegWrite <= 1;Sftmd <= 0;Jrn <= 0;Lui <= 0;RegDst <= 0;ALUSrc <= 1;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;end6'b000100:  // beqbeginALUop <= 4'b0011;RegWrite <= 0;Sftmd <= 0;Jrn <= 0;Lui <= 0;RegDst <= 0;ALUSrc <= 0;Zero_sign_ex <= 1;Branch <= 1;nBranch <= 0;end6'b000101:  // bnebeginALUop <= 4'b0011;RegWrite <= 0;Sftmd <= 0;Jrn <= 0;Lui <= 0;RegDst <= 0;ALUSrc <= 0;Zero_sign_ex <= 1;Branch <= 0;nBranch <= 1;enddefault:beginRegWrite <= 0;Sftmd <= 0;ALUop <= 4'b1111;Jrn <= 0;Lui <= 0;RegDst <= 0;ALUSrc <= 0;Zero_sign_ex <= 0;Branch <= 0;nBranch <= 0;endendcase
endendmodule

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 control/*** I-type ***/input [15:0] imm, // data// controlinput Lui,           // 1:lui instructioninput ALUSrc,        // 1:imm calculateinput Zero_sign_ex,  // 0:zero extension; 1:sign extensionoutput reg [31:0] ALUresult,// beq bne output [31:0] offset,    output zero  // ALUresult == 0 => zero = 1;);// convert A and B to signed numbers
wire signed [31:0] A_signed = A;
wire signed [31:0] B_signed;
wire signed [31:0] B_signed_origin = B; // for sra instruction// 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};/*** I-type: data select ***/// immediate data extension and select
wire [31:0] zero_imm_ex = {16'b0,imm};
wire [31:0] sign_imm_ex = (imm[15] == 1)? {16'hffff,imm}: {16'b0,imm}; // NOTE: 16'b1 is incorrect
wire [31:0] imm_input = (Zero_sign_ex == 0)? zero_imm_ex: sign_imm_ex;// R[rt] or imm extension
wire [31:0] B_select = (ALUSrc == 0)? B: imm_input;
assign B_signed = B_select;// output: (sign extension)offset << 2
assign offset = imm_input << 2;/* calculate */
always @(*)
begincase (ALUop)4'b0000:    // add addibeginALUresult <= A + B_select;end4'b0001:    // addu addiubeginALUresult <= A + B_select;end4'b0010:    // subbeginALUresult <= A - B;end4'b0011:    // sububeginALUresult <= A - B;// zero <= ((A-B) == 0)? 1: 0; // beqend4'b0100:    // and andibeginALUresult <= A & B_select;end4'b0101:    // or oribeginALUresult <= A | B_select;end4'b0110:    // xor xoribeginALUresult <= A ^ B_select;end4'b0111:    // nor noribeginALUresult <= ~(A | B_select);end4'b1000:    // slt slti // note:********signed********//beginif(A_signed < B_signed)ALUresult <= 1;elseALUresult <= 0;end4'b1001:    // sltu sltiubeginif(A < B_select)ALUresult <= 1;elseALUresult <= 0;end4'b1010:    // sllv 10  /*** note: not B_select ***/beginALUresult <= 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_origin >>> A_or_Shift;    // NOTE: not A_signed >> B!end4'b1101: // luibeginALUresult <= (Lui == 1)? {imm,16'b0}: 0;enddefault:beginALUresult <= 0;endendcase
endassign zero = (ALUresult == 0)? 1: 0;endmodule

注意ALU的zero信号,就是判断ALUresult是不是0,是的话就是1

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,   // 100MHz input rst_n,output [31:0] result // 测试syntheses,没有输出的模块是恐怖的);/
/******* clk *******/
/// cpu_clk Inputs
// reg   clk;   // cpu_clk Outputs
wire  clk_div; // 20Mhzcpu_clk  u_cpu_clk (.clk_in1                 ( clk        ),.clk_out1                ( clk_div    )
);//
/******** PC ********/
//// pc_1 Inputs
wire  Jrn;
wire  [31:0]  JrPC;wire [31:0] offset_in;
wire zero_in;
wire Branch_in;
wire nBranch_in;// pc_1 Outputs
wire  [31:0]  pcOld;pc_1  u_pc_1 (.clk                     ( clk_div     ),.rst_n                   ( rst_n   ),.pcOrigin                ( pcOld   ),.JrPC                    ( JrPC    ),.Jrn                     ( Jrn     ),.offset                  ( offset_in  ),.zero                    ( zero_in    ),.Branch                  ( Branch_in  ),.nBranch                 ( nBranch_in ),.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;
wire   RegDst_in;// reg_files_1 Outputs
wire  [31:0]  A;    // rs
wire  [31:0]  B;    // rt
assign JrPC = A;reg_files_1  u_reg_files_1 (.clk                     ( clk_div         ),.rst_n                   ( rst_n       ),.rA                      ( instruction[25:21]          ),.rB                      ( instruction[20:16]          ),.rW                      ( instruction[15:11]          ),.writeData               ( ALUresult   ),.RegWrite                ( RegWrite    ),.RegDst                  ( RegDst_in   ),.A                       ( A           ),.B                       ( B           ));///
/******** ALU ********/
///// ALU_1 Inputs
// wire   [31:0]  A;
// wire   [31:0]  B;
wire   [3:0]  ALUop;
wire   Sftmd;wire   [15:0] imm = instruction[15:0];
wire Lui_in;
wire ALUSrc_in;
wire Zero_sign_ex_in;// ALU_1 Outputs
// wire  [31:0]  ALUresult = writeData; // Note:Error!
wire  [31:0]  offset;
wire  zero;assign offset_in = offset;
assign zero_in = zero;ALU_1  u_ALU_1 (.A                       ( A           ),.B                       ( B           ),.shamt                   ( instruction[10:6]),.ALUop                   ( ALUop       ),.Sftmd                   ( Sftmd       ),/** I-type **/.imm                     ( imm              ),.Lui                     ( Lui_in           ),.ALUSrc                  ( ALUSrc_in        ),.Zero_sign_ex            ( Zero_sign_ex_in  ),.ALUresult               ( ALUresult        ),.offset                  ( offset           ),.zero                    ( zero             ));/
/******** 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;
wire Lui;
wire RegDst;
wire ALUSrc;
wire Zero_sign_ex;
wire Branch;
wire nBranch;// send to Reg Files
assign RegDst_in = RegDst;
// send to ALU
assign Lui_in = Lui;
assign ALUSrc_in = ALUSrc;
assign Zero_sign_ex_in = Zero_sign_ex;
// send to pc
assign Branch_in = Branch;
assign nBranch_in = nBranch;control_1  u_control_1 (.op                      ( instruction[31:26]         ),.func                    ( instruction[5:0]       ),.RegWrite                ( RegWrite   ),.Sftmd                   ( Sftmd      ),.ALUop                   ( ALUop      ),.Jrn                     ( Jrn        ),// I type.Lui                     ( Lui        ),.RegDst                  ( RegDst     ),.ALUSrc                  ( ALUSrc     ),.Zero_sign_ex            ( Zero_sign_ex ),// beq bne.Branch                  ( Branch     ),.nBranch                 ( nBranch    ));assign result = ALUresult;endmodule

仿真,综合,实现

成功!

还没有开发板下载验证。

`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,   // 100MHz input rst_n,output [31:0] result // 测试syntheses,没有输出的模块是恐怖的);/
/******* clk *******/
/// cpu_clk Inputs
// reg   clk;   // cpu_clk Outputs
wire  clk_div; // 20Mhzcpu_clk  u_cpu_clk (.clk_in1                 ( clk        ),.clk_out1                ( clk_div    )
);//
/******** PC ********/
//// pc_1 Inputs
wire  Jrn;
wire  [31:0]  JrPC;wire [31:0] offset_in;
wire zero_in;
wire Branch_in;
wire nBranch_in;// pc_1 Outputs
wire  [31:0]  pcOld;pc_1  u_pc_1 (.clk                     ( clk_div     ),.rst_n                   ( rst_n   ),.pcOrigin                ( pcOld   ),.JrPC                    ( JrPC    ),.Jrn                     ( Jrn     ),.offset                  ( offset_in  ),.zero                    ( zero_in    ),.Branch                  ( Branch_in  ),.nBranch                 ( nBranch_in ),.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;
wire   RegDst_in;// reg_files_1 Outputs
wire  [31:0]  A;    // rs
wire  [31:0]  B;    // rt
assign JrPC = A;reg_files_1  u_reg_files_1 (.clk                     ( clk_div         ),.rst_n                   ( rst_n       ),.rA                      ( instruction[25:21]          ),.rB                      ( instruction[20:16]          ),.rW                      ( instruction[15:11]          ),.writeData               ( ALUresult   ),.RegWrite                ( RegWrite    ),.RegDst                  ( RegDst_in   ),.A                       ( A           ),.B                       ( B           ));///
/******** ALU ********/
///// ALU_1 Inputs
// wire   [31:0]  A;
// wire   [31:0]  B;
wire   [3:0]  ALUop;
wire   Sftmd;wire   [15:0] imm = instruction[15:0];
wire Lui_in;
wire ALUSrc_in;
wire Zero_sign_ex_in;// ALU_1 Outputs
// wire  [31:0]  ALUresult = writeData; // Note:Error!
wire  [31:0]  offset;
wire  zero;assign offset_in = offset;
assign zero_in = zero;ALU_1  u_ALU_1 (.A                       ( A           ),.B                       ( B           ),.shamt                   ( instruction[10:6]),.ALUop                   ( ALUop       ),.Sftmd                   ( Sftmd       ),/** I-type **/.imm                     ( imm              ),.Lui                     ( Lui_in           ),.ALUSrc                  ( ALUSrc_in        ),.Zero_sign_ex            ( Zero_sign_ex_in  ),.ALUresult               ( ALUresult        ),.offset                  ( offset           ),.zero                    ( zero             ));/
/******** 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;
wire Lui;
wire RegDst;
wire ALUSrc;
wire Zero_sign_ex;
wire Branch;
wire nBranch;// send to Reg Files
assign RegDst_in = RegDst;
// send to ALU
assign Lui_in = Lui;
assign ALUSrc_in = ALUSrc;
assign Zero_sign_ex_in = Zero_sign_ex;
// send to pc
assign Branch_in = Branch;
assign nBranch_in = nBranch;control_1  u_control_1 (.op                      ( instruction[31:26]         ),.func                    ( instruction[5:0]       ),.RegWrite                ( RegWrite   ),.Sftmd                   ( Sftmd      ),.ALUop                   ( ALUop      ),.Jrn                     ( Jrn        ),// I type.Lui                     ( Lui        ),.RegDst                  ( RegDst     ),.ALUSrc                  ( ALUSrc     ),.Zero_sign_ex            ( Zero_sign_ex ),// beq bne.Branch                  ( Branch     ),.nBranch                 ( nBranch    ));assign result = ALUresult;endmodule

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/384637.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【算法】学习笔记(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操作的都是逻辑…

html基础元素案例笔记(1)

这是代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>CSS FlexBox test</title><link rel"stylesheet" type"text/css" href"./css/index.css"></head><body>…

C语言中的struct和union区别

参考&#xff1a;Difference between Structure and Union in C 二者区别 struct 这里不做详细说明&#xff0c;因为参考链接中都写明了。只做一些重点强调。 struct中声明的变量&#xff0c;在分配空间的时候&#xff0c;struct结构空间大小&#xff0c;大于等于其内部所有…

C语言多文件编译链接为1个可执行文件的简单原理

参考1&#xff1a;C header files and compilation/linking 参考2&#xff1a;计算机系统基础&#xff08;一&#xff09;袁春风 &#xff08;符号链接部分&#xff09; 我们现在有一个简单的工程&#xff0c;有这么几个文件 1.t1.h extern int x;void tt();t1.c #include &…

Java读写二维数组到文件

1. 创建文件 使用了File类中的createrNewFile方法。 public static boolean createFile(String filename){try{File file new File(filename);file.createNewFile();return true;} catch (IOException e) {e.printStackTrace();return false;}}查阅文档可知&#xff0c;若文件…

如何掌握java API的方法

如何掌握方法的使用&#xff1f; 查文档文档不一定看得懂&#xff0c;亲自试一试就知道了&#xff01; 这俩方法没啥好说的&#xff0c;自己体会即可&#xff01; 注意&#xff01;先看原版英文文档&#xff0c;然后自己试一试&#xff0c;就能更加理解了&#xff0c;然后&a…

Leetcode1512. 好数对的数目 抽出本质原型 利用范围条件

解法1&#xff1a;暴力枚举 class Solution {public int numIdenticalPairs(int[] nums) {int count 0;for(int i 0;i < nums.length; i){for(int j i 1; j < nums.length; j){if(nums[i] nums[j])count;}}return count;} }没啥可说的&#xff0c;就是小学数学问题…