cpu速成1

主要模块

顶级模块(top)
内存(dmem和imem)
寄存器文件(regfile)
算术逻辑单元(alu)
控制单元(controller)
数据通路(datapath)
在这里插入图片描述
大致块图

信号列表

module top(input  logic        clk_in1_p, 
           input  logic        clk_in1_n, 
           input  logic        reset,                         
           output logic [7:0] led);

这是顶级模块(top),它是处理器的最外层接口。clk_in1_p 和 clk_in1_n 表示差分时钟信号输入,reset 是重置信号,用于初始化处理器状态;led 是输出信号,可能用来指示某些状态或用于调试。
在这里插入图片描述
完整块图

变量定义

  logic [31:0] PC, Instr, ReadData;
  logic [31:0] WriteData, DataAdr;
  logic      clk,  MemWrite;

在顶级模块内部定义了一些逻辑向量,PC 代表程序计数器,Instr 是指令寄存器,ReadData 和 WriteData 用于数据的读取和写入。DataAdr 表示数据存储地址。clk 是内部时钟信号,MemWrite 是一个布尔标志,用于指示是否执行内存写操作

  // instantiate processor and memories
  clk_wiz_0 u_clk_wiz
      (
       // Clock out ports
       .clk_out1(clk),     // output clk_out1
      // Clock in ports
       .clk_in1_p(clk_in1_p),    // input clk_in1_p
       .clk_in1_n(clk_in1_n));    // input clk_in1_n

这里创建了一个时钟向导(clk_wiz_0)实例用于生成处理器所需的时钟信号。

  riscvsingle rvsingle(clk, reset, PC, Instr, MemWrite, DataAdr,                       WriteData, ReadData,led);
  imem imem(PC, Instr);
  dmem dmem(clk, MemWrite, DataAdr, WriteData, ReadData);
endmodule

riscvsingle 是RISC-V处理器的主要实例,imem 是指令内存,dmem 是数据内存的实例。这些实例化允许这些模块在顶级模块中运作。

module riscvsingle(input  logic        clk, reset,
                   output logic [31:0] PCF,
                   input  logic [31:0] Instr,
                   output logic        MemWriteM,
                   output logic [31:0] ALUResultM, WriteDataM,
                   input  logic [31:0] ReadDataM,
                   output logic [7:0] led);

RISC-V单周期处理器的核心实现,它包含所有设计的主要功能部分,比如指令解析、执行和存储器访问。

controller c(clk, reset,InstrD[6:0], InstrD[14:12], InstrD[30], ZeroE,flushE,
             ImmSrcD,ALUSrcE,ResultSrcE0,PCSrcE,alucontrolE,
             RegWriteM, MemWriteM,
             ResultSrcW,RegWriteW
             );

controller模块负责生成控制信号,指导数据路径如何响应指令。其参数分别对应时钟、复位信号、指令操作码、函数码、分支逻辑等。

datapath dp(clk, reset, ImmSrcD, ALUSrcE,ResultSrcE0,PCSrcE,alucontrolE,RegWriteM,
              ResultSrcW,  RegWriteW,ZeroE,flushE,PCF,InstrF,InstrD,ALUResultM, WriteDataM,ReadDataM,led);

datapath模块实现指令的执行路径。这包括从指令内存获取指令、指令解码、寄存器文件读写、以及算术逻辑单元(ALU)等操作。

module maindec(input  logic [6:0] op,
               output logic [1:0] ResultSrc,
               output logic       MemWrite,
               output logic       Branch, ALUSrc,
               output logic       RegWrite, Jump,
               output logic [1:0] ImmSrc,
               output logic [1:0] ALUOp);
// ...
endmodule

maindec模块根据操作码解码指令,生成如分支、跳转、寄存器写入等控制信号。

module aludec(input  logic       opb5,
              input  logic [2:0] funct3,
              input  logic       funct7b5, 
              input  logic [1:0] ALUOp,
              output logic [2:0] ALUControl);
// ...
endmodule

aludec模块负责生成ALU的控制信号,指导ALU如何对操作数执行操作(如加法、减法、逻辑运算等)。

module datapath(input  logic        clk, reset,
// ...
endmodule

这里是datapath模块,它处理寄存器之间的数据移动,以及与ALU、内存的交互。

module hazard(
  input logic [4: 0] rs1D,
  input logic [4: 0] rs2D,
  // ... (其余参数省略)
  output logic stallF,
  output logic stallD,
  output logic flushD,
  output logic flushE
);
// ... (模块内部实现)
endmodule

hazard模块负责检测并解决数据冒险问题。数据冒险是指当前指令需要读取的数据,还没有被前一条指令写回的情况。
举例来说,如果指令需要使用的寄存器数据还没有被前面的指令写回,那么流水线就需要插入停顿(stall)来等待需要的数据。模块内部的逻辑会检测流水线中各种可能的冒险情况,并产生相应的控制信号来处理。

module regfile(input  logic        clk, 
               input  logic        we3, 
               input  logic [ 4:0] a1, a2, a3, 
               input  logic [31:0] wd3, 
               output logic [31:0] rd1, rd2,
               output logic [7:0] led);
// ... (模块内部实现)
endmodule

regfile表示寄存器文件,它提供对32个32位寄存器的读写操作。we3为写使能信号,a1和a2为读取寄存器的地址,a3和wd3用于写入数据。rd1和rd2为输出数据,led用做显示输出或者调试。

module adder(input  [31:0] a, b,
             output [31:0] y);
// ...
endmodule

adder是一个加法器模块,用于计算地址或者指令中的偏移。

module extend(input  logic [31:7] instr,
              input  logic [1:0]  immsrc,
              output logic [31:0] immext);
// ...
endmodule

extend用于指令中立即数的扩展,根据实际操作类型扩展符号位。

module alu(input  logic [31:0] a, b,
           input  logic [2:0]  alucontrol,
           output logic [31:0] result,
           output logic        zero);
// ...
endmodule

alu是算术逻辑单元模块,根据alucontrol控制信号的不同进行运算(例如加法、与运算、或运算等)并产生结果。

// 模块 flopr (寄存器)
module flopr #(parameter WIDTH = 8)
              (input  logic             clk, reset,
               input  logic [WIDTH-1:0] d, 
               output logic [WIDTH-1:0] q);

  always_ff @(posedge clk, posedge reset)
    if (reset) q <= 0;
    else       q <= d;
endmodule

flopr模块是一个参数化的D-触发器,可以用来构建同步寄存器。在时钟的上升沿,如果reset信号为高,则输出q被清零;否则,输入d的值则会被传递到输出q。

// 模块 floprc (带清除功能的寄存器)
module floprc #(parameter WIDTH = 8)
              (input                  clk, reset, clear,
               input      [WIDTH-1:0] d, 
               output reg [WIDTH-1:0] q);

  always_ff @(posedge clk, posedge reset)
    if (reset)      q <= #1 0;
    else if (clear) q <= #1 0;
    else            q <= #1 d;
endmodule

floprc模块扩展了flopr,增加了一个clear信号。如果clear信号为高,不仅在复位期间,而且在时钟周期内任何时候,输出q都会被清零。

// 模块 flopenr (带使能信号的寄存器)
module flopenr #(parameter WIDTH = 8)
                (input                  clk, reset,
                 input                  en,
                 input      [WIDTH-1:0] d, 
                 output reg [WIDTH-1:0] q);
 
  always_ff @(posedge clk, posedge reset)
    if      (reset) q <= #1 0;
    else if (en)    q <= #1 d;
endmodule

flopenr模块为寄存器增加了一个使能(en)信号。当en为高时,输入d的值会在时钟上升沿被加载到输出q;当en为低时,输出q保持不变。

// 模块 flopenrc (带使能和清除信号的寄存器)
module flopenrc #(parameter WIDTH = 8, parameter VALUE_0 = 32'b0)
                 (input                  clk, reset,
                  input                  en, clear,
                  input      [WIDTH-1:0] d, 
                  output reg [WIDTH-1:0] q);
 
  always_ff @(posedge clk, posedge reset)
    if      (reset) q <= #1 VALUE_0;
    else if (clear) q <= #1 VALUE_0;
    else if (en)    q <= #1 d;
endmodule

flopenrc模块结合了使能和清除功能。在时钟上升沿,如果复位(reset)或清除(clear)信号为高,则输出q被设置为0或VALUE_0值;如果两者都低,则仅在使能(en)为高时,输入d的值才会传递给输出q。

// 模块 mux2 (2路选择器)
module mux2 #(parameter WIDTH = 8)
             (input  logic [WIDTH-1:0] d0, d1, 
              input  logic             s, 
              output logic [WIDTH-1:0] y);

  assign y = s ? d1 : d0; 
endmodule

mux2模块是一个简单的2输入多路选择器。根据选择信号s的值,输出y等于输入d0或d1。

// 模块 mux3 (3路选择器)
module mux3 #(parameter WIDTH = 8)
             (input  logic [WIDTH-1:0] d0, d1, d2,
              input  logic [1:0]       s, 
              output logic [WIDTH-1:0] y);

  assign y = s[1] ? d2 : (s[0] ? d1 : d0);
endmodule

mux3模块是一个3输入选择器。根据两位选择信号s的值,输出y等于输入d0、d1或d2中的一个。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值