1.通用寄存器,三个通用寄存器,两个读取,一个写入
gpr
input wire clk,
input wire reset,
/********** 读端口0 **********/
input wire [`RegAddrBus] rd_addr_0, // Read address 位宽5
output wire [`WordDataBus] rd_data_0, // Read data 位宽32
/********** 读端口1 **********/
input wire [`RegAddrBus] rd_addr_1, // Read address 位宽5
output wire [`WordDataBus] rd_data_1, // Read data 位宽32
/********** 写端口 **********/
input wire we_, // Write enable 位宽1
input wire [`RegAddrBus] wr_addr, // Write address 位宽5
input wire [`WordDataBus] wr_data // Write data 位宽32
2.SPM专用内存
spm
input wire clk,
//portA:IF阶段
input wire [`SpmAddrBus] if_spm_addr, // Address 位宽12
input wire if_spm_as_, // Address strobe
input wire if_spm_rw, // Read/Write
input wire [`WordDataBus] if_spm_wr_data, // Write data 位宽32
output wire [`WordDataBus] if_spm_rd_data, // Read data 位宽32
//portB:MEM阶段
input wire [`SpmAddrBus] mem_spm_addr, // Address 位宽12
input wire mem_spm_as_, // Address strobe
input wire mem_spm_rw, // Read/Write
input wire [`WordDataBus] mem_spm_wr_data, // Write data 位宽32
output wire [`WordDataBus] mem_spm_rd_data // Read data 位宽32
1.通用寄存器Gpr:
指令最大可以指定三个寄存器为操作数,
其中两个寄存器读取值,然后向另一个寄存器写入值。因此寄存器堆为两个读取端口,一个写入端口
代码如下:
/********** Global header **********/
`include "nettype.vh"
`include "global_config.vh"
`include "stddef.vh"
/********** Local header **********/
`include "cpu.vh"
module gpr(
//时钟和复位
input wire clk,
input wire reset,
/********** 读端口0 **********/
input wire [`RegAddrBus] rd_addr_0, // Read address 位宽5
output wire [`WordDataBus] rd_data_0, // Read data 位宽32
/********** 读端口1 **********/
input wire [`RegAddrBus] rd_addr_1, // Read address 位宽5
output wire [`WordDataBus] rd_data_1, // Read data 位宽32
/********** 写端口 **********/
input wire we_, // Write enable 位宽1
input wire [`RegAddrBus] wr_addr, // Write address 位宽5
input wire [`WordDataBus] wr_data // Write data 位宽32
);
/********** Internal signal **********/
reg [`WordDataBus] gpr [`REG_NUM-1:0]; // Register array 32*32
integer i; //初始化用迭代器,位宽32
//读取端口0
assign rd_data_0 =((we_==`ENABLE)&&(wr_addr==rd_addr_0))?
wr_data:gpr[rd_addr_0];
//读取端口1
assign rd_data_1 =((we_==`ENABLE)&&(wr_addr==rd_addr_1))?
wr_data:gpr[rd_addr_1];
//异步复位
always @(posedge clk or `RESET_EDGE reset)
begin
if(reset==`RESET_ENABLE)
begin
for (i=0;i<`REG_NUM;i=i+1)
//`define REG_NUM 32
begin
//`define WORD_DATA_W 32
gpr[i] <= #1 `WORD_DATA_W'h0;
end
end
else
begin
if(we_==`ENABLE_)
begin
gpr[wr_addr]<= #1 wr_data;
end
end
end
endmodule
2.专用内存SPM
CPU可以不经过总线直接访问的专用内存。在(IF阶段和MEM阶段使用)存储器使用FPGA的Dual Port RAM 实现。
代码如下:
/********** Global header **********/
`include "nettype.vh"
`include "global_config.vh"
`include "stddef.vh"
/********** Local header **********/
`include "spm.vh"
module spm(
//时钟
input wire clk,
//portA:IF阶段
input wire [`SpmAddrBus] if_spm_addr, // Address 位宽12
input wire if_spm_as_, // Address strobe
input wire if_spm_rw, // Read/Write
input wire [`WordDataBus] if_spm_wr_data, // Write data 位宽32
output wire [`WordDataBus] if_spm_rd_data, // Read data 位宽32
//portB:MEM阶段
input wire [`SpmAddrBus] mem_spm_addr, // Address 位宽12
input wire mem_spm_as_, // Address strobe
input wire mem_spm_rw, // Read/Write
input wire [`WordDataBus] mem_spm_wr_data, // Write data 位宽32
output wire [`WordDataBus] mem_spm_rd_data // Read data 位宽32
);
/********** Write enable signal写入有效信号 **********/
reg wea; // Port A
reg web; // Port B
//写入有效信号的生成
always @(*)
begin
//A端口
// `define WRITE 1'b0
// `define MEM_ENABLE 1'b1
//`define MEM_DISABLE 1'b0
if((if_spm_as_==`ENABLE_)&&(if_spm_rw==`WRITE))
begin
wea =`MEM_ENABLE;
end
else
begin
wea=`MEM_DISABLE;
end
//B端口
if((mem_spm_as_==`ENABLE_)&&(mem_spm_rw==`WRITE))
begin
web =`MEM_ENABLE;
end
else
begin
web=`MEM_DISABLE;
end
end
/********** Xilinx FPGA Block RAM : Dual port RAM **********/
//利用赛灵思FPGA的块RAM模块
x_s3e_dpram x_s3e_dpram (
/********** Port A : IF stage **********/
.clka (clk),
.addra (if_spm_addr),
.dia (if_spm_wr_data),
.wea (wea),
.doa (if_spm_rd_data),
/********** Port B : MEM stage **********/
.clkb (clk),
.addrb (mem_spm_addr),
.dib (mem_spm_wr_data),
.web (web),
.dob (mem_spm_rd_data)
);
endmodule
//FPGA的块RAM模块
/********** Global header **********/
`include "nettype.vh"
`include "stddef.vh"
`include "global_config.vh"
/********** Local header **********/
`include "spm.vh"
/********** Module **********/
module x_s3e_dpram (
/********** Port A **********/
input wire clka, // Clock
input wire [`SpmAddrBus] addra, // Address
input wire [`WordDataBus] dina, // Write data
input wire wea, // Write enable
output reg [`WordDataBus] douta, // Read data
/********** Port B **********/
input wire clkb, // Clock
input wire [`SpmAddrBus] addrb, // Address
input wire [`WordDataBus] dinb, // Write data
input wire web, // Write enable
output reg [`WordDataBus] doutb // Read data
);
//`define SPM_DEPTH 4096 // SPM's depth
//`define WordDataBus 31:0 // Data bus
/********** Memory **********/
reg [`WordDataBus] mem [0:`SPM_DEPTH-1];
/********** Memory access Port A **********/
always @(posedge clka) begin
// Read access
if ((web == `ENABLE) && (addra == addrb)) begin
douta <= #1 dinb;
end else begin
douta <= #1 mem[addra];
end
// Write access
if (wea == `ENABLE) begin
mem[addra]<= #1 dina;
end
end
/********** Memory access (Port B) **********/
always @(posedge clkb) begin
// Read access
if ((wea == `ENABLE) && (addrb == addra)) begin
doutb <= #1 dina;
end else begin
doutb <= #1 mem[addrb];
end
// Write access
if (web == `ENABLE) begin
mem[addrb]<= #1 dinb;
end
end
endmodule
/*****************************************************/
/****************************************************/
端口定义:
IF阶段操作:取指令,并决定下一条PC寄存器的内容。
IF阶段由流水线寄存器与总线接口组成。
1.bus_if 总线接口
/********** Clock & Reset **********/
input wire clk,
input wire reset,
/********** Pipeline control signal **********/
input wire stall, //流水线延迟信号
input wire flush, //流水线刷新信号
output reg busy, //流水线总线忙信号
/********** CPU interface **********/
input wire [`WordAddrBus] addr, //位宽30
input wire as_, // Address enable
input wire rw, // Read/Write
input wire [`WordDataBus] wr_data, //位宽32
output reg [`WordDataBus] rd_data, //数据输出口,位宽32
/********** SPM interface **********/
input wire [`WordDataBus] spm_rd_data, // Read data 32
output wire [`WordAddrBus] spm_addr, // Address 30
output reg spm_as_, // Address strobe
output wire spm_rw, // Read/Write
output wire [`WordDataBus] spm_wr_data, // Write data 32
/********** Bus interface **********/
input wire [`WordDataBus] bus_rd_data, // Read data 32
input wire bus_rdy_, // Ready
input wire bus_grnt_, // Bus grant
output reg bus_req_, // Bus request
output reg [`WordAddrBus] bus_addr, // Address 30
output reg bus_as_, // Address strobe
output reg bus_rw, // Read/Write
output reg [`WordDataBus] bus_wr_data // Write data 32
四个状态机,总线接口由俩个部分组成,一部分是控制内存访问的组合电路,另一部分是控制总线接口状态的时序电路。
2.if_reg
/********** Clock & Reset **********/
input wire clk,
input wire reset,
/********** Fetch data **********/
input wire [`WordDataBus] insn, // Fetched instruction 32位
/********** Pipeline control signal **********/
input wire stall,
input wire flush,
input wire [`WordAddrBus] new_pc, // New program counter 位宽30
input wire br_taken, // Branch taken 分支成立
input wire [`WordAddrBus] br_addr, // Branch address 分支目标地址 位宽30
/********** IF/ID pipeline register **********/
output reg [`WordAddrBus] if_pc, // Program counter 位宽30
output reg [`WordDataBus] if_insn, // Instruction 指令 位宽32
output reg if_en // Enable pipeline data 流水线数据有效标志位
3.if_stage
/********** Clock & Reset **********/
input wire clk,
input wire reset,
/********** SPM interface **********/
input wire [`WordDataBus] spm_rd_data, // Read data
output wire [`WordAddrBus] spm_addr, // Address
output wire spm_as_, // Address strobe
output wire spm_rw, // Read/Write
output wire [`WordDataBus] spm_wr_data, // Write data
/********** Bus interface **********/
input wire [`WordDataBus] bus_rd_data, // Read data
input wire bus_rdy_, // Ready
input wire bus_grnt_, // Bus grant
output wire bus_req_, // Bus request
output wire [`WordAddrBus] bus_addr, // Address
output wire bus_as_, //Address strobe
output wire bus_rw, // Read/Write
output wire [`WordDataBus] bus_wr_data, // Write data
/********** Pipeline control signal **********/
input wire stall, // Stall
input wire flush, // Flush
input wire [`WordAddrBus] new_pc, // New program counter
input wire br_taken, // Branch taken
input wire [`WordAddrBus] br_addr, // Branch address
output wire busy, // Busy signal
/********** IF/ID pipeline register **********/
output wire [`WordAddrBus] if_pc, // Program counter
output wire [`WordDataBus] if_insn, // Instruction
output wire if_en // Enable pipeline data
3.总线接口
使用状态机
代码如下:
/********** Global header **********/
`include "nettype.vh"
`include "global_config.vh"
`include "stddef.vh"
/********** Local header **********/
`include "cpu.vh"
`include "bus.vh"
module bus_if(
/********** Clock & Reset **********/
input wire clk,
input wire reset,
/********** Pipeline control signal **********/
input wire stall, //流水线延迟信号
input wire flush, //流水线刷新信号
output reg busy, //流水线总线忙信号
/********** CPU interface **********/
input wire [`WordAddrBus] addr, //位宽30
input wire as_, // Address enable
input wire rw, // Read/Write
input wire [`WordDataBus] wr_data, //位宽32
output reg [`WordDataBus] rd_data, //数据输出口,位宽32
/********** SPM interface **********/
input wire [`WordDataBus] spm_rd_data, // Read data 32
output wire [`WordAddrBus] spm_addr, // Address 30
output reg spm_as_, // Address strobe
output wire spm_rw, // Read/Write
output wire [`WordDataBus] spm_wr_data, // Write data 32
/********** Bus interface **********/
input wire [`WordDataBus] bus_rd_data, // Read data 32
input wire bus_rdy_, // Ready
input wire bus_grnt_, // Bus grant
output reg bus_req_, // Bus request
output reg [`WordAddrBus] bus_addr, // Address 30
output reg bus_as_, // Address strobe
output reg bus_rw, // Read/Write
output reg [`WordDataBus] bus_wr_data // Write data 32
);
/********** Internal signal **********/
reg [`BusIfStateBus] state; // Status of bus interface 2
reg [`WordDataBus] rd_buf; // Read buffer 32
wire [`BusSlaveIndexBus] s_index; // Bus slave index 3(从属有8个)
//`define BusSlaveIndexLoc 29:27
//生成总线从属索引
assign s_index = addr[`BusSlaveIndexLoc];
/**********输出的赋值*******************/
assign spm_addr=addr;
assign spm_rw =rw;
assign spm_wr_data=wr_data;
/***************1.内存访问控制****************/
always@(*)
begin
//代入初始值
rd_data = `WORD_DATA_W'h0;
spm_as_=`DISABLE_;
busy = `DISABLE;
/*总线接口状态*/
/*
// Status
`define BUS_IF_STATE_IDLE 2'h0 // Idle
`define BUS_IF_STATE_REQ 2'h1 // Bus request
`define BUS_IF_STATE_ACCESS 2'h2 // Bus access
`define BUS_IF_STATE_STALL 2'h3 // Stall
*/
case(state)
`BUS_IF_STATE_IDLE :begin //空闲状态
//内存访问,主要实现SPM和CPU之间的连接
if((flush==`DISABLE)&&(as_==`ENABLE_))begin
//开始内存访问操作,选择访问目标
if(s_index == `BUS_SLAVE_1) begin//访问SPM `define BUS_SLAVE_1 1
if(stall ==`DISABLE) begin//检测延时是否发生,此时流水线非延迟
spm_as_ =`ENABLE_;
if(rw==`READ) begin
rd_data= spm_rd_data;//把SPM读取的数据输出到数据输出端口
end
end
end
else begin
busy =`ENABLE;//SPM访问在一个周期就可以实现,如果不是SPM从属,则需要访问总线,使得总线busy
end
end
end
//请求总线
`BUS_IF_STATE_REQ : begin
busy=`ENABLE; //此时总线访问正在进行,总线忙信号有效
end
//访问总线
`BUS_IF_STATE_ACCESS : begin
//等待就绪信号
if (bus_rdy_ == `ENABLE) begin //就绪信号使能时,总线访问介绍,当rw为读取信号时,
if(rw==`READ) begin
rd_data=bus_rd_data; //总线的读取信号输出给读取端口
end
end
else begin
busy=`ENABLE; //当就绪信号无效时,说明总线访问正在进行,总线忙
end
end
//延迟
`BUS_IF_STATE_STALL : begin
if(rw ==`READ) begin //等待延迟解除时,如果rw为读信号,因为总线访问已经结束,
//直接把缓存数据,输出给读取端口。并使得忙信号无效
rd_data =rd_buf;
end
end
endcase
end
/********** Control bus interface status **********/
/****************2.总线接口控制*********************/
always@(posedge clk , `RESET_EDGE reset) begin
if(reset == `RESET_ENABLE) begin
//异步复位
state <= #1 `BUS_IF_STATE_IDLE;
bus_req_ <= #1 `DISABLE_;
bus_addr <= #1 `WORD_ADDR_W'h0;
bus_as_ <= #1 `DISABLE_;
bus_rw <= #1 `READ;
bus_wr_data <= #1 `WORD_DATA_W'h0;
rd_buf <= #1 `WORD_DATA_W'h0;
end
else begin
//总线接口状态,主要实现状态机的转变
case(state)
`BUS_IF_STATE_IDLE : begin //空闲
if ((flush == `DISABLE) && (as_ == `ENABLE_)) begin
if(s_index != `BUS_SLAVE_1) begin
state <= #1 `BUS_IF_STATE_REQ;
bus_req_ <= #1 `ENABLE_;
bus_addr <= #1 addr;
bus_rw <= #1 rw;
bus_wr_data <=wr_data;
end
end
end
//请求总线
`BUS_IF_STATE_REQ: begin
//等待总线许可
if(bus_grnt_==`ENABLE_)begin //获得总线使用权
state <= #1 `BUS_IF_STATE_ACCESS;
bus_as_ <= #1 `ENABLE_;
end
end
`BUS_IF_STATE_ACCESS : begin
bus_as_ <= #1 `DISABLE_;//地址选通无效
//等待就绪信号
if(bus_rdy_ ==`ENABLE_) begin
//释放总线,信号数据初始化
bus_req_ <= #1 `DISABLE_;
bus_addr <= #1 `WORD_ADDR_W'h0;
bus_rw <= #1 `READ;
bus_wr_data <= #1 `WORD_DATA_W'h0;
//保存读取到的数据
if (bus_rw==`READ)begin
rd_buf <= #1 bus_rd_data;
end
if(stall == `ENABLE)begin //发生延迟
state <= #1 `BUS_IF_STATE_STALL;
end else begin
state <= #1 `BUS_IF_STATE_IDLE;
end
end
end
`BUS_IF_STATE_STALL : begin //延迟
//检测延时是否发生
if(stall ==`DISABLE) begin
state <= #1 `BUS_IF_STATE_IDLE;
end
end
endcase
end
end
endmodule
4.IF阶段流水线寄存器
实现取指,并决定下一条PC寄存器的内容
/********** Global header **********/
`include "nettype.vh"
`include "global_config.vh"
`include "stddef.vh"
/********** Local header **********/
`include "isa.vh"
`include "cpu.vh"
module if_reg(
/********** Clock & Reset **********/
input wire clk,
input wire reset,
/********** Fetch data **********/
input wire [`WordDataBus] insn, // Fetched instruction 32位
/********** Pipeline control signal **********/
input wire stall,
input wire flush,
input wire [`WordAddrBus] new_pc, // New program counter 位宽30
input wire br_taken, // Branch taken 分支成立
input wire [`WordAddrBus] br_addr, // Branch address 分支目标地址 位宽30
/********** IF/ID pipeline register **********/
output reg [`WordAddrBus] if_pc, // Program counter 位宽30
output reg [`WordDataBus] if_insn, // Instruction 指令 位宽32
output reg if_en // Enable pipeline data 流水线数据有效标志位
);
/*************流水线寄存器*********************/
always @(posedge clk or `RESET_EDGE reset) begin
if(reset == `RESET_ENABLE) begin
//异步复位
//`define RESET_VECTOR 30'h0 // Reset header
//`define ISA_NOP 32'h0
if_pc <= #1 `RESET_VECTOR;
if_insn <= #1 `ISA_NOP;
if_en <= #1 `DISABLE;
end else
begin
//更新流水线寄存器
if (stall == `DISABLE) begin
if (flush ==`ENABLE) begin //刷新流水线,PC值更新
if_pc <= #1 new_pc;
if_insn <= #1 `ISA_NOP;
if_en <= #1 `DISABLE;
end
else if (br_taken ==`ENABLE) begin//PC更新为分支目标地址
if_pc <= #1 br_addr;
if_insn <= #1 insn;
if_en <= #1 `ENABLE;
end
else begin
if_pc <= #1 if_pc + 1'd1;
if_insn <= #1 insn;
if_en <= #1 `ENABLE;
end
end
end
end
endmodule
5.TOP模块,连接各个模块
代码如下:
/********** Global header **********/
`include "nettype.vh"
`include "global_config.vh"
`include "stddef.vh"
/********** Local header **********/
`include "cpu.vh"
module if_stage(
/********** Clock & Reset **********/
input wire clk,
input wire reset,
/********** SPM interface **********/
input wire [`WordDataBus] spm_rd_data, // Read data
output wire [`WordAddrBus] spm_addr, // Address
output wire spm_as_, // Address strobe
output wire spm_rw, // Read/Write
output wire [`WordDataBus] spm_wr_data, // Write data
/********** Bus interface **********/
input wire [`WordDataBus] bus_rd_data, // Read data
input wire bus_rdy_, // Ready
input wire bus_grnt_, // Bus grant
output wire bus_req_, // Bus request
output wire [`WordAddrBus] bus_addr, // Address
output wire bus_as_, //Address strobe
output wire bus_rw, // Read/Write
output wire [`WordDataBus] bus_wr_data, // Write data
/********** Pipeline control signal **********/
input wire stall, // Stall
input wire flush, // Flush
input wire [`WordAddrBus] new_pc, // New program counter
input wire br_taken, // Branch taken
input wire [`WordAddrBus] br_addr, // Branch address
output wire busy, // Busy signal
/********** IF/ID pipeline register **********/
output wire [`WordAddrBus] if_pc, // Program counter
output wire [`WordDataBus] if_insn, // Instruction
output wire if_en // Enable pipeline data
);
/********** Internal signal **********/
wire [`WordDataBus] insn; // Fetched instruction
/********** Bus interface **********/
bus_if bus_if (
/********** Clock & Reset **********/
.clk (clk),
.reset (reset),
/********** Pipeline control signal **********/
.stall (stall),
.flush (flush),
.busy (busy),
/********** CPU interface **********/
.addr (if_pc),
.as_ (`ENABLE_), //每个周期都需要取指,as信号之间挂高
.rw (`READ), //IF只要READ不需要WRITE
.wr_data (`WORD_DATA_W'h0), //IF只要READ不需要WRITE
.rd_data (insn),
/********** Scratchpad memory interface **********/
.spm_rd_data (spm_rd_data),
.spm_addr (spm_addr),
.spm_as_ (spm_as_),
.spm_rw (spm_rw),
.spm_wr_data (spm_wr_data),
/********** Bus interface **********/
.bus_rd_data (bus_rd_data),
.bus_rdy_ (bus_rdy_),
.bus_grnt_ (bus_grnt_),
.bus_req_ (bus_req_),
.bus_addr (bus_addr),
.bus_as_ (bus_as_),
.bus_rw (bus_rw),
.bus_wr_data (bus_wr_data)
);
/********** IF stage pipeline register **********/
if_reg if_reg (
/********** Clock & Reset **********/
.clk (clk),
.reset (reset),
/********** Fetch data **********/
.insn (insn), // Fetched instruction
/********** Pipeline control signal **********/
.stall (stall),
.flush (flush),
.new_pc (new_pc),
.br_taken (br_taken),
.br_addr (br_addr),
/********** IF/ID pipeline register **********/
.if_pc (if_pc),
.if_insn (if_insn),
.if_en (if_en)
);
endmodule
6.仿真
仿真思路:
IF阶段:输入PC地址,在对应内存拿到指令,输出。
观察TOP模块的连接端口,
先是bus_if总线接口,实现CPU和SPM的连接,实现取出指令。
然后是if的流水线寄存器,给PC输出指令。
我们先利用if寄存器,给出PC(这边指向SPM内存),PC值输入给bus_if接口addr,其中s_index将会取出addr高3位,连接到SPM中,将spm中的rd_dat赋值给rd_data输出;而rd_data将会和指令数据连接insn,最后由if寄存器输出对应的指令(if_insn)
代码如下:
`include"nettype.vh"
`include"stddef.vh"
`include"global_config.vh"
`include"bus.vh"
`include"rom.vh"
module If_test(
);
//端口定义
/********** Clock & Reset **********/
reg clk;
reg reset;
/********** SPM interface **********/
reg [`WordDataBus] spm_rd_data; // Read data
wire [`WordAddrBus] spm_addr; // Address
wire spm_as_; // Address strobe
wire spm_rw; // Read/Write
wire [`WordDataBus] spm_wr_data; // Write data
/********** Bus interface **********/
wire [`WordDataBus] bus_rd_data; // Read data
wire bus_rdy_; // Ready
reg bus_grnt_; // Bus grant
wire bus_req_; // Bus request
wire [`WordAddrBus] bus_addr; // Address
wire bus_as_; //Address strobe
wire bus_rw; // Read/Write
wire [`WordDataBus] bus_wr_data; // Write data
/********** Pipeline control signal **********/
reg stall; // Stall
reg flush; // Flush
reg [`WordAddrBus] new_pc; // New program counter
reg br_taken; // Branch taken
reg [`WordAddrBus] br_addr; // Branch address
wire busy; // Busy signal
/********** IF/ID pipeline register **********/
wire [`WordAddrBus] if_pc; // Program counter
wire [`WordDataBus] if_insn; // Instruction
wire if_en; // Enable pipeline data
wire [`WordDataBus] insn;
integer i;
parameter STEP=100;
always#(STEP/2)begin
clk<=~clk;
end
//实例化
bus_if bus_if (
/********** Clock & Reset **********/
.clk (clk),
.reset (reset),
/********** Pipeline control signal **********/
.stall (stall),
.flush (flush),
.busy (busy),
/********** CPU interface **********/
.addr (if_pc),
.as_ (`ENABLE_), //每个周期都需要取指,as信号之间挂高
.rw (`READ), //IF只要READ不需要WRITE
.wr_data (`WORD_DATA_W'h0), //IF只要READ不需要WRITE
.rd_data (insn),
/********** Scratchpad memory interface **********/
.spm_rd_data (spm_rd_data),
.spm_addr (spm_addr),
.spm_as_ (spm_as_),
.spm_rw (spm_rw),
.spm_wr_data (spm_wr_data),
/********** Bus interface **********/
.bus_rd_data (bus_rd_data),
.bus_rdy_ (bus_rdy_),
.bus_grnt_ (bus_grnt_),
.bus_req_ (bus_req_),
.bus_addr (bus_addr),
.bus_as_ (bus_as_),
.bus_rw (bus_rw),
.bus_wr_data (bus_wr_data)
);
/********** IF stage pipeline register **********/
if_reg if_reg (
/********** Clock & Reset **********/
.clk (clk),
.reset (reset),
/********** Fetch data **********/
.insn (insn), // Fetched instruction
/********** Pipeline control signal **********/
.stall (stall),
.flush (flush),
.new_pc (new_pc),
.br_taken (br_taken),
.br_addr (br_addr),
/********** IF/ID pipeline register **********/
.if_pc (if_pc),
.if_insn (if_insn),
.if_en (if_en)
);
//测试
initial begin
#10 begin
clk<=1;
reset<=`RESET_ENABLE;
end
#(STEP*3/4)
#STEP begin
reset<=`RESET_DISABLE;
#STEP
stall <=`DISABLE;
#STEP
new_pc<={{3'b001},{27{1'b0}}};
flush<=`ENABLE;
#STEP
flush<=`DISABLE;
#STEP
spm_rd_data <= 32'hffff_ffff;
end
#STEP
$finish;
end
endmodule
仿真结果:
通过newpc刷新IF流水线,这时PC指向SPM地址,bus_if模块中CPU将取出SPM的数据,输出给if流水线寄存器。
SPM的数据输出给insn
仿真完成