单指令周期MIPS模型机系统结构示意图
MIPS指令格式
我是将模型机部署在sword板上,在FPGA实现模型机的运行。
BCD.V
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 10:53:22 06/28/2018
// Design Name:
// Module Name: BCD
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module BCD(input [31:0]in,output reg[63:0]out);
always@(in)
begin
case(in[3:0])
4'b0000: out[7:0]=8'b00000011;
4'b0001: out[7:0]=8'b10011111;
4'b0010: out[7:0]=8'b00100101;
4'b0011: out[7:0]=8'b00001101;
4'b0100: out[7:0]=8'b10011001;
4'b0101: out[7:0]=8'b01001001;
4'b0110: out[7:0]=8'b01000001;
4'b0111: out[7:0]=8'b00011111;
4'b1000: out[7:0]=8'b00000001;
4'b1001: out[7:0]=8'b00001001;
4'b1010: out[7:0]=8'b00010001;
4'b1011: out[7:0]=8'b11000001;
4'b1100: out[7:0]=8'b01100011;
4'b1101: out[7:0]=8'b10000101;
4'b1110: out[7:0]=8'b01100001;
4'b1111: out[7:0]=8'b01110001;
default:out[7:0]=8'b11111111;
endcase
case(in[7:4])
4'b0000: out[15:8]=8'b00000011;
4'b0001: out[15:8]=8'b10011111;
4'b0010: out[15:8]=8'b00100101;
4'b0011: out[15:8]=8'b00001101;
4'b0100: out[15:8]=8'b10011001;
4'b0101: out[15:8]=8'b01001001;
4'b0110: out[15:8]=8'b01000001;
4'b0111: out[15:8]=8'b00011111;
4'b1000: out[15:8]=8'b00000001;
4'b1001: out[15:8]=8'b00001001;
4'b1010: out[15:8]=8'b00010001;
4'b1011: out[15:8]=8'b11000001;
4'b1100: out[15:8]=8'b01100011;
4'b1101: out[15:8]=8'b10000101;
4'b1110: out[15:8]=8'b01100001;
4'b1111: out[15:8]=8'b01110001;
default:out[15:8]=8'b11111111;
endcase
case(in[11:8])
4'b0000: out[23:16]=8'b00000011;
4'b0001: out[23:16]=8'b10011111;
4'b0010: out[23:16]=8'b00100101;
4'b0011: out[23:16]=8'b00001101;
4'b0100: out[23:16]=8'b10011001;
4'b0101: out[23:16]=8'b01001001;
4'b0110: out[23:16]=8'b01000001;
4'b0111: out[23:16]=8'b00011111;
4'b1000: out[23:16]=8'b00000001;
4'b1001: out[23:16]=8'b00001001;
4'b1010: out[23:16]=8'b00010001;
4'b1011: out[23:16]=8'b11000001;
4'b1100: out[23:16]=8'b01100011;
4'b1101: out[23:16]=8'b10000101;
4'b1110: out[23:16]=8'b01100001;
4'b1111: out[23:16]=8'b01110001;
default:out[23:16]=8'b11111111;
endcase
case(in[15:12])
4'b0000: out[31:24]=8'b00000011;
4'b0001: out[31:24]=8'b10011111;
4'b0010: out[31:24]=8'b00100101;
4'b0011: out[31:24]=8'b00001101;
4'b0100: out[31:24]=8'b10011001;
4'b0101: out[31:24]=8'b01001001;
4'b0110: out[31:24]=8'b01000001;
4'b0111: out[31:24]=8'b00011111;
4'b1000: out[31:24]=8'b00000001;
4'b1001: out[31:24]=8'b00001001;
4'b1010: out[31:24]=8'b00010001;
4'b1011: out[31:24]=8'b11000001;
4'b1100: out[31:24]=8'b01100011;
4'b1101: out[31:24]=8'b10000101;
4'b1110: out[31:24]=8'b01100001;
4'b1111: out[31:24]=8'b01110001;
default:out[31:24]=8'b11111111;
endcase
case(in[19:16])
4'b0000: out[39:32]=8'b00000011;
4'b0001: out[39:32]=8'b10011111;
4'b0010: out[39:32]=8'b00100101;
4'b0011: out[39:32]=8'b00001101;
4'b0100: out[39:32]=8'b10011001;
4'b0101: out[39:32]=8'b01001001;
4'b0110: out[39:32]=8'b01000001;
4'b0111: out[39:32]=8'b00011111;
4'b1000: out[39:32]=8'b00000001;
4'b1001: out[39:32]=8'b00001001;
4'b1010: out[39:32]=8'b00010001;
4'b1011: out[39:32]=8'b11000001;
4'b1100: out[39:32]=8'b01100011;
4'b1101: out[39:32]=8'b10000101;
4'b1110: out[39:32]=8'b01100001;
4'b1111: out[39:32]=8'b01110001;
default:out[39:32]=8'b11111111;
endcase
case(in[23:20])
4'b0000: out[47:40]=8'b00000011;
4'b0001: out[47:40]=8'b10011111;
4'b0010: out[47:40]=8'b00100101;
4'b0011: out[47:40]=8'b00001101;
4'b0100: out[47:40]=8'b10011001;
4'b0101: out[47:40]=8'b01001001;
4'b0110: out[47:40]=8'b01000001;
4'b0111: out[47:40]=8'b00011111;
4'b1000: out[47:40]=8'b00000001;
4'b1001: out[47:40]=8'b00001001;
4'b1010: out[47:40]=8'b00010001;
4'b1011: out[47:40]=8'b11000001;
4'b1100: out[47:40]=8'b01100011;
4'b1101: out[47:40]=8'b10000101;
4'b1110: out[47:40]=8'b01100001;
4'b1111: out[47:40]=8'b01110001;
default:out[47:40]=8'b11111111;
endcase
case(in[27:24])
4'b0000: out[55:48]=8'b00000011;
4'b0001: out[55:48]=8'b10011111;
4'b0010: out[55:48]=8'b00100101;
4'b0011: out[55:48]=8'b00001101;
4'b0100: out[55:48]=8'b10011001;
4'b0101: out[55:48]=8'b01001001;
4'b0110: out[55:48]=8'b01000001;
4'b0111: out[55:48]=8'b00011111;
4'b1000: out[55:48]=8'b00000001;
4'b1001: out[55:48]=8'b00001001;
4'b1010: out[55:48]=8'b00010001;
4'b1011: out[55:48]=8'b11000001;
4'b1100: out[55:48]=8'b01100011;
4'b1101: out[55:48]=8'b10000101;
4'b1110: out[55:48]=8'b01100001;
4'b1111: out[55:48]=8'b01110001;
default:out[55:48]=8'b11111111;
endcase
case(in[31:28])
4'b0000: out[63:56]=8'b00000011;
4'b0001: out[63:56]=8'b10011111;
4'b0010: out[63:56]=8'b00100101;
4'b0011: out[63:56]=8'b00001101;
4'b0100: out[63:56]=8'b10011001;
4'b0101: out[63:56]=8'b01001001;
4'b0110: out[63:56]=8'b01000001;
4'b0111: out[63:56]=8'b00011111;
4'b1000: out[63:56]=8'b00000001;
4'b1001: out[63:56]=8'b00001001;
4'b1010: out[63:56]=8'b00010001;
4'b1011: out[63:56]=8'b11000001;
4'b1100: out[63:56]=8'b01100011;
4'b1101: out[63:56]=8'b10000101;
4'b1110: out[63:56]=8'b01100001;
4'b1111: out[63:56]=8'b01110001;
default:out[63:56]=8'b11111111;
endcase
end
endmodule
clk_div.v
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 17:19:38 07/17/2012
// Design Name:
// Module Name: clk_div
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module clk_div(input clk,
input rst,
input SW15,
output reg[31:0]clkdiv,
output Clk_CPU
);
// Clock divider-时钟分频器
always @ (posedge clk ) begin
if (rst) clkdiv <= 0; else clkdiv <= clkdiv + 1'b1; end
assign Clk_CPU = clkdiv[24];
endmodule
defines.v
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 17:19:38 07/17/2012
// Design Name:
// Module Name: defines
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
`define RstEnable 1'b1
`define RstDisable 1'b0
`define ZeroWord 32'h00000000
`define WriteEnable 1'b1
`define WriteDisable 1'b0
`define ReadEnable 1'b1
`define ReadDisable 1'b0
`define AluOpBus 7:0
`define AluSelBus 2:0
`define InstValid 1'b0
`define InstInvalid 1'b1
`define Stop 1'b1
`define NoStop 1'b0
`define InDelaySlot 1'b1
`define NotInDelaySlot 1'b0
`define Branch 1'b1
`define NotBranch 1'b0
`define InterruptAssert 1'b1
`define InterruptNotAssert 1'b0
`define TrapAssert 1'b1
`define TrapNotAssert 1'b0
`define True_v 1'b1
`define False_v 1'b0
`define ChipEnable 1'b1
`define ChipDisable 1'b0
`define IOBase 32'hfffff000
`define EXE_AND 6'b100100
`define EXE_OR 6'b100101
`define EXE_XOR 6'b100110
`define EXE_NOR 6'b100111
`define EXE_ANDI 6'b001100
`define EXE_ORI 6'b001101
`define EXE_XORI 6'b001110
`define EXE_LUI 6'b001111
`define EXE_ADDI 6'b001000
`define EXE_ADD 6'b100000
`define EXE_SUB 6'b100010
`define EXE_SLL 6'b000000
`define EXE_SRL 6'b000010
`define EXE_SRA 6'b000011
`define EXE_MULT 6'b011000
`define EXE_MUL 6'b000010
`define EXE_LW 6'b100011
`define EXE_SW 6'b101011
`define EXE_J 6'b000010
`define EXE_JAL 6'b000011
`define EXE_JR 6'b001000
`define EXE_BEQ 6'b000100
`define EXE_BNE 6'b000101
`define EXE_NOP 6'b000000
`define SSNOP 32'b00000000000000000000000001000000
`define EXE_SPECIAL_INST 6'b000000
`define EXE_REGIMM_INST 6'b000001
`define EXE_SPECIAL2_INST 6'b011100
//AluOp
`define EXE_AND_OP 8'b00100100
`define EXE_OR_OP 8'b00100101
`define EXE_XOR_OP 8'b00100110
`define EXE_NOR_OP 8'b00100111
`define EXE_ANDI_OP 8'b01011001
`define EXE_ORI_OP 8'b01011010
`define EXE_XORI_OP 8'b01011011
`define EXE_LUI_OP 8'b01011100
`define EXE_ADDI_OP 8'b01001000
`define EXE_ADD_OP 8'b00100000
`define EXE_SUB_OP 8'b00100010
`define EXE_SLL_OP 8'b01111100
`define EXE_SRL_OP 8'b00000010
`define EXE_SRA_OP 8'b00000011
`define EXE_MULT_OP 8'b00011000
`define EXE_MUL_OP 8'b10101001
`define EXE_LW_OP 8'b11100011
`define EXE_SW_OP 8'b11101011
`define EXE_J_OP 8'b01001111
`define EXE_JAL_OP 8'b01010000
`define EXE_JR_OP 8'b00001000
`define EXE_BEQ_OP 8'b01010001
`define EXE_BNE_OP 8'b01010010
`define EXE_NOP_OP 8'b00000000
//AluSel
`define EXE_RES_LOGIC 3'b001
`define EXE_RES_SHIFT 3'b010
`define EXE_RES_MOVE 3'b011
`define EXE_RES_ARITHMETIC 3'b100
`define EXE_RES_MUL 3'b101
`define EXE_RES_JUMP_BRANCH 3'b110
`define EXE_RES_LOAD_STORE 3'b111
`define EXE_RES_NOP 3'b000
//inst_rom
`define InstAddrBus 31:0
`define InstBus 31:0
`define InstMemNum 511//131071
`define InstMemNumLog2 10//17
`define KeyBus 15:0
`define SEGBus 31:0
//regfile
`define RegAddrBus 4:0
`define RegBus 31:0
`define RegWidth 32
`define DoubleRegWidth 64
`define DoubleRegBus 63:0
`define RegNum 32
`define RegNumLog2 5
`define NOPRegAddr 5'b00000
//mem
`define MemBus 31:0
`define MemAddrBus 31:0
`define MemWidth 32
`define DataMemNum 511 //131071
`define DataMemNumLog2 10 //17
//IO
`define IONum 511//4095
`define IOWidth 32
`define IOBus 31:0
`define IOAddrBus 31:0
`define IONumLog2 10//12
//IO _ Addr
`define SEG_ADDR 32'hFFFFF000
`define LED_ADDR 32'hFFFFF004
`define KEY_ADDR 32'hFFFFF008
`define BUTTON_ADDR 32'hFFFFF00c
指令寄存器rom.v
`timescale 1ns / 1ps
`include "defines.v"
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 08:36:20 07/03/2018
// Design Name:
// Module Name: rom
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module inst_rom(input wire ce,
input wire [`InstAddrBus] addr,
output reg [`InstBus] inst);
reg [`InstBus] inst_mem [`InstMemNum-1:0];
//initial $readmemh ("G:\init_h.txt",inst_mem);
initial
begin
inst_mem[0] = 32'h340200ff;//ori 0x00ff
// inst_mem[1] = 32'hafc20004;
inst_mem[1] = 32'h8fc50008;//key input
inst_mem[2] = 32'hafc50004;//led output
inst_mem[3] = 32'hafc50000;//seg output
inst_mem[4] = 32'h08000001;//j
end
always@(*)
if(ce == `ChipDisable)
inst <= `ZeroWord;
else
inst <= inst_mem[addr[`InstMemNumLog2+1:2]];
endmodule
top.v
`include "defines.v"
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 17:19:38 07/17/2012
// Design Name:
// Module Name: top
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module OpenMIPS(input wire rst,
input wire clk,
input wire [`RegBus] rom_data_i,
output wire [`RegBus] rom_addr_o,
output wire rom_ce_o,
input wire [`KeyBus] key,
output [`SEGBus] SEG,
output [`KeyBus] LED
);
//ID to Pc
wire[`RegBus] branch_addr;
wire branch_flag;
//ID to EX
wire[`AluOpBus] id_aluop;
wire[`AluSelBus] id_alusel;
wire[`RegBus] id_reg1;
wire[`RegBus] id_reg2;
wire id_wreg;
wire[`RegAddrBus] id_wd;
wire[`RegBus] link_addr;
wire[`InstAddrBus] inst;
//ID to Regfile
wire reg1_read;
wire reg2_read;
wire[`RegBus] reg1_data;
wire[`RegBus] reg2_data;
wire[`RegAddrBus] reg1_addr;
wire[`RegAddrBus] reg2_addr;
//EX to WB
wire ex_wreg;
wire[`RegAddrBus] ex_wd;
wire[`RegBus] ex_wdata;
wire[`AluOpBus] ex_aluop;
wire[`MemAddrBus] ex_memaddr;
wire[`MemBus] ex_reg1data;
wire[`MemBus] ex_reg2data;
//WB to Regfile
wire[`RegAddrBus] wb_wd;
wire wb_wreg;
wire[`RegBus] wb_wdata;
/*
//WB to MIOC
wire[`MemBus] mem_wmemdata;
wire[`MemAddrBus] mem_memaddr;
wire mem_wmem;
wire mem_mce;
wire[3:0] mem_msel;
wire[`MemBus] mem_rm_idata;//MEM input into WB
*/
//HILO to ex
wire[`RegBus] ex_hi;
wire[`RegBus] ex_lo;
//HI - LO to ex input
wire[`RegBus] HILO_hi;
wire[`RegBus] HILO_lo;
wire HILO_whilo;
//wb to mioc input
wire ior;
wire iow;
wire [`MemBus] rm_idata;
wire [`MemBus] wm_idata;
wire [`MemAddrBus] m_iaddr;
wire mw;
wire mr;
wire [3:0] msel;
//MIOC to Mem output
wire[`MemBus] rmdata;
wire[`MemBus] wmdata;
wire[`MemAddrBus] maddr;
wire memw;
wire mce;
wire[3:0] MI_msel;
//MIOC to IO output
wire [`IOBus] wiodata;
wire [`IOBus] riodata;
wire iow1;
wire ice;
wire [`IOAddrBus] ioaddr;
//IO to FPGA
wire [`SEGBus] SEG;
wire [`KeyBus] LED;
wire rst_sig = !rst;
//pc_reg real
pc_reg pc_reg0(
.clk(clk),
.rst(rst_sig),
.branch_addr_i(branch_addr),
.branch_flag_i(branch_flag),
.pc(rom_addr_o),
.ce(rom_ce_o)
);
//ID real
id id0(
.rst(rst_sig),
.pc_i(rom_addr_o),
.inst_i(rom_data_i),
//Regfile - id input
.reg1_data_i(reg1_data), .reg2_data_i(reg2_data),
//id - Regfile output
.reg1_read_o(reg1_read), .reg2_read_o(reg2_read),
.reg1_addr_o(reg1_addr), .reg2_addr_o(reg2_addr),
//id - EX output
.link_addr_o(link_addr),
.inst_o(inst),
.aluop_o(id_aluop), .alusel_o(id_alusel),
.reg1_o(id_reg1), .reg2_o(id_reg2),
.wd_o(id_wd), .wreg_o(id_wreg),
//id - pc output
.branch_addr_o(branch_addr),
.branch_flag_o(branch_flag)
);
//Regfile real
regfile regfile1(
.clk(clk),
.rst(rst_sig),
//WB-regfile input
.we(wb_wreg), .waddr(wb_wd),
.wdata(wb_wdata),
//ID-regfile input
.re1(reg1_read), .raddr1(reg1_addr),
.rdata1(reg1_data),
.re2(reg2_read), .raddr2(reg2_addr),
.rdata2(reg2_data)
);
//EX real
ex ex0(
.rst(rst_sig),
//ID-ex input
.link_addr_i(link_addr),
.inst_i(inst),
.aluop_i(id_aluop), .alusel_i(id_alusel),
.reg1_i(id_reg1), .reg2_i(id_reg2),
.wd_i(id_wd), .wreg_i(id_wreg),
//HI?LO?????
.hi_i(ex_hi),
.lo_i(ex_lo),
.hi_o(HILO_hi),
.lo_o(HILO_lo),
.whilo_o(HILO_whilo),
// ex-WB output
.aluop_o(ex_aluop),
.memaddr_o(ex_memaddr),
.reg1data_o(ex_reg1data),//
.reg2data_o(ex_reg2data),
.wd_o(ex_wd),
.wreg_o(ex_wreg),
.wdata_o(ex_wdata)
);
hilo_reg hilo_reg1(
.clk(clk),
.rst(rst_sig),
.we(HILO_whilo),
.hi_i(HILO_hi),
.lo_i(HILO_lo),
.hi_o(ex_hi),
.lo_o(ex_lo)
);
//WB real
wb wb0(
.rst(rst_sig),
//ex - wb input
.aluop_i(ex_aluop),
.memaddr_i(ex_memaddr),
.rmemdata_i(rm_idata),
.reg1data_i(ex_reg1data),
.reg2data_i(ex_reg2data),
// input
.ex_wd(ex_wd),
.ex_wreg(ex_wreg),
.ex_wdata(ex_wdata),
//Wb-regfile output
.wb_wd(wb_wd), .wb_wreg(wb_wreg),
.wb_wdata(wb_wdata),
//wb - mem-ram output
.mem_wmemdata_o(wm_idata),
.mem_memaddr_o(m_iaddr),
.mem_wmem_o(mw),
.mem_rmem_o(mr),
.mem_msel_o(msel),
.iow(iow),
.ior(ior)
);
MIOC MIOC1(//wb to mioc input
.rst(rst_sig),
.ior_i(ior),
.iow_i(iow),
.rm_idata_o(rm_idata),
.wm_idata_i(wm_idata),
.m_iaddr_i(m_iaddr),
.mw_i(mw),
.mr_i(mr),
.msel_i(msel),
//MIOC to Mem output
.rmdata_i(rmdata),
.wmdata_o(wmdata),
.maddr_o(maddr),
.memw_o(memw),
.mce_o(mce),
.msel_o(MI_msel),
//MIOC to IO output
.wiodata_o(wiodata),
.riodata_i(riodata),
.iow_o(iow1),
.ice_o(ice),
.ioaddr_o(ioaddr)
);
//MEM real
mem mem1(
.clk(clk),
.mem_wmemdata_i(wmdata),
.mem_memaddr_i(maddr),
.mem_wmem_i(memw),
.mem_msel_i(MI_msel),
.mem_mce_i(mce),
.rmemdata_o(rmdata)
);
IO IO1(
.addr_i(ioaddr),
.ce_i(ice),
.iow_i(iow1),
.rdata_o(riodata),
.wdata_i(wiodata),
.clk(clk),
.rst(rst_sig),
.key(key),
.SEG(SEG),
.LED(LED)
);
endmodule
module mem(
input wire clk,
input wire [`MemBus] mem_wmemdata_i,
input wire [`MemAddrBus] mem_memaddr_i,
input wire mem_wmem_i,
input wire [3:0] mem_msel_i,
input wire mem_mce_i,
output reg[`MemBus] rmemdata_o
);
reg [`MemBus] ram [`DataMemNum-1:0];
always@(*)
begin
if(mem_mce_i == `ChipDisable)//ce=0 read
begin
rmemdata_o <= `ZeroWord;
end
else
begin
rmemdata_o<=ram[mem_memaddr_i[`DataMemNumLog2+1:2]];
end
end
always@(posedge clk)
begin
if(mem_mce_i == `ChipEnable && mem_wmem_i == `WriteEnable)
begin
ram[mem_memaddr_i[`DataMemNumLog2+1:2]]<=mem_wmemdata_i;
end
end
endmodule
module pc_reg(input wire clk,
input wire rst,
input wire [`RegBus] branch_addr_i,
input wire branch_flag_i,
output reg [`InstAddrBus] pc,
output reg ce);
always@(posedge clk)
if(rst == `RstEnable)
ce <= `ChipDisable;
else
ce <= `ChipEnable;
always@(posedge clk)
if(ce == `ChipDisable)
pc <= `ZeroWord;
else if(branch_flag_i == `Branch)
pc <= branch_addr_i;
else
pc <= pc + 4'h4;
endmodule
// HI-LO
module hilo_reg(
input wire clk,
input wire rst,
//???
input wire we,
input wire[`RegBus] hi_i,
input wire[`RegBus] lo_i,
//???1
output reg[`RegBus] hi_o,
output reg[`RegBus] lo_o
);
always @ (posedge clk) begin
if (rst == `RstEnable) begin
hi_o <= `ZeroWord;
lo_o <= `ZeroWord;
end else if((we == `WriteEnable)) begin
hi_o <= hi_i;
lo_o <= lo_i;
end
end
endmodule
module regfile(
input wire clk,
input wire rst,
//wb-reg input
input wire we,
input wire[`RegAddrBus] waddr,
input wire[`RegBus] wdata,
//id-reg 1
input wire re1,
input wire[`RegAddrBus] raddr1,
output reg[`RegBus] rdata1,
//id-reg 2
input wire re2,
input wire[`RegAddrBus] raddr2,
output reg[`RegBus] rdata2
);
//32 bit 32 depth
reg[`RegBus] regs[0:`RegNum-1];
initial
begin
regs[1]=32'hffff0000;
regs[2]=32'h0000ffff;
regs[3]=32'h0fff0000;
regs[4]=32'h00ff0000;
regs[30]=32'hfffff000;
end
//???
always @ (posedge clk) begin
if(rst==`RstDisable)begin
if((we==`WriteEnable) && (waddr != `RegNumLog2'h0))begin
regs[waddr]<=wdata;
end
end
end
//read reg1
always @ (*) begin
if(rst==`RstEnable) begin
rdata1<=`ZeroWord;
end
else if(raddr1==`RegNumLog2'h0) begin
rdata1<=`ZeroWord;
end
else if(re1==`ReadEnable) begin
rdata1<=regs[raddr1];
end
else begin
rdata1<=`ZeroWord;
end
end
//read reg2
always @ (*) begin
if(rst==`RstEnable) begin
rdata2<=`ZeroWord;
end
else if(raddr2==`RegNumLog2'h0) begin
rdata2<=`ZeroWord;
end
else if(re2==`ReadEnable) begin
rdata2<=regs[raddr2];
end
else begin
rdata2<=`ZeroWord;
end
end
endmodule
module id(
input wire rst,
input wire[`InstAddrBus] pc_i,
input wire[`InstBus] inst_i,
//Regfile - id input
input wire[`RegBus] reg1_data_i,
input wire[`RegBus] reg2_data_i,
//Id - pc output
output reg[`RegBus] branch_addr_o,
output reg branch_flag_o,
//Id - Regfile output
output reg reg1_read_o,
output reg reg2_read_o,
output reg[`RegAddrBus] reg1_addr_o,
output reg[`RegAddrBus] reg2_addr_o,
//ID- Ex output
output reg[`RegBus] link_addr_o,
output reg[`InstAddrBus] inst_o,
output reg[`AluOpBus] aluop_o,
output reg[`AluSelBus] alusel_o,
output reg[`RegBus] reg1_o,
output reg[`RegBus] reg2_o,
output reg[`RegAddrBus] wd_o,
output reg wreg_o
);
wire [5:0] op = inst_i[31:26];//I!=0 _ R=000000
wire [4:0] op2 = inst_i[10:6];
wire [5:0] op3 = inst_i[5:0];
wire [4:0] op4 = inst_i[20:16];//wregaddr rt
reg[`RegBus] imm;
reg instvalid;
wire[`RegBus] pc_plus_4;
wire[`RegBus] pc_plus_8;
wire[`RegBus] imm_sll2_signedext;
//jump attribute
assign pc_plus_4 = pc_i + 3'b100;//j inst nextinst adress
assign pc_plus_8 = pc_i + 4'b1000;//save jal inst return inst adress
assign imm_sll2_signedext = {{14{inst_i[15]}}, inst_i[15:0], 2'b00 }; //imm extend jump address
always@(*)
if(rst == `RstEnable)
begin
aluop_o <= `EXE_NOP_OP;
alusel_o <= `EXE_RES_NOP;
wd_o <= `NOPRegAddr;
wreg_o <= `WriteDisable;
instvalid <= `InstValid;
reg1_read_o <= 1'b0;
reg2_read_o <= 1'b0;
reg1_addr_o <= `NOPRegAddr;
reg2_addr_o <= `NOPRegAddr;
imm <= 32'h0;
link_addr_o <= `ZeroWord;
inst_o <= `ZeroWord;
branch_addr_o <= `ZeroWord;
branch_flag_o <= `NotBranch;
//SW need inst
inst_o <= inst_i;
end
else
begin
aluop_o <= `EXE_NOP_OP;
alusel_o <= `EXE_RES_NOP;
wd_o <= inst_i[15:11];
wreg_o <= `WriteDisable;
instvalid <= `InstInvalid;
reg1_read_o <= 1'b0;
reg2_read_o <= 1'b0;
reg1_addr_o <= inst_i[25:21];
reg2_addr_o <= inst_i[20:16];
imm <= `ZeroWord;
link_addr_o <= `ZeroWord;
inst_o <= `ZeroWord;
branch_addr_o <= `ZeroWord;
branch_flag_o <= `NotBranch;
//SW need inst
inst_o <= inst_i;
case (op)
`EXE_SPECIAL_INST: begin
case (op2)
5'b00000: begin
case (op3)
`EXE_OR: begin
wreg_o <= `WriteEnable; aluop_o <= `EXE_OR_OP;
alusel_o <= `EXE_RES_LOGIC; reg1_read_o <= 1'b1; reg2_read_o <= 1'b1;
instvalid <= `InstValid;
end
`EXE_AND: begin
wreg_o <= `WriteEnable; aluop_o <= `EXE_AND_OP;
alusel_o <= `EXE_RES_LOGIC; reg1_read_o <= 1'b1; reg2_read_o <= 1'b1;
instvalid <= `InstValid;
end
`EXE_XOR: begin
wreg_o <= `WriteEnable; aluop_o <= `EXE_XOR_OP;
alusel_o <= `EXE_RES_LOGIC; reg1_read_o <= 1'b1; reg2_read_o <= 1'b1;
instvalid <= `InstValid;
end
`EXE_ADD: begin
wreg_o <= `WriteEnable; aluop_o <= `EXE_ADD_OP;
alusel_o <= `EXE_RES_ARITHMETIC; reg1_read_o <= 1'b1; reg2_read_o <= 1'b1;
instvalid <= `InstValid;
end
`EXE_SUB: begin
wreg_o <= `WriteEnable; aluop_o <= `EXE_SUB_OP;
alusel_o <= `EXE_RES_ARITHMETIC; reg1_read_o <= 1'b1; reg2_read_o <= 1'b1;
instvalid <= `InstValid;
end
`EXE_MULT: begin
wreg_o <= `WriteDisable; aluop_o <= `EXE_MULT_OP;
reg1_read_o <= 1'b1; reg2_read_o <= 1'b1; instvalid <= `InstValid;
end
`EXE_JR: begin
wreg_o <= `WriteDisable; aluop_o <= `EXE_JR_OP;
alusel_o <= `EXE_RES_JUMP_BRANCH; reg1_read_o <= 1'b1; reg2_read_o <= 1'b0;
link_addr_o <= `ZeroWord;
branch_addr_o <= reg1_o;
branch_flag_o <= `Branch;
instvalid <= `InstValid;
end
default: begin
end
endcase
end
default: begin
end
endcase
end
`EXE_ORI: begin //ORI??
wreg_o <= `WriteEnable; aluop_o <= `EXE_OR_OP;
alusel_o <= `EXE_RES_LOGIC; reg1_read_o <= 1'b1; reg2_read_o <= 1'b0;
imm <= {16'h0, inst_i[15:0]}; wd_o <= inst_i[20:16];
instvalid <= `InstValid;
end
`EXE_ANDI: begin
wreg_o <= `WriteEnable; aluop_o <= `EXE_AND_OP;
alusel_o <= `EXE_RES_LOGIC; reg1_read_o <= 1'b1; reg2_read_o <= 1'b0;
imm <= {16'h0, inst_i[15:0]}; wd_o <= inst_i[20:16];
instvalid <= `InstValid;
end
`EXE_XORI: begin
wreg_o <= `WriteEnable; aluop_o <= `EXE_XOR_OP;
alusel_o <= `EXE_RES_LOGIC; reg1_read_o <= 1'b1; reg2_read_o <= 1'b0;
imm <= {16'h0, inst_i[15:0]}; wd_o <= inst_i[20:16];
instvalid <= `InstValid;
end
`EXE_ADDI: begin //addi
wreg_o <= `WriteEnable; aluop_o <= `EXE_ADD_OP;
alusel_o <= `EXE_RES_ARITHMETIC; reg1_read_o <= 1'b1; reg2_read_o <= 1'b0;
imm <= {{16{inst_i[15]}}, inst_i[15:0]}; wd_o <= inst_i[20:16];
instvalid <= `InstValid;
end
`EXE_LUI: begin
wreg_o <= `WriteEnable; aluop_o <= `EXE_OR_OP;
alusel_o <= `EXE_RES_LOGIC; reg1_read_o <= 1'b1; reg2_read_o <= 1'b0;
imm <= {inst_i[15:0], 16'h0}; wd_o <= inst_i[20:16];
instvalid <= `InstValid;
end
`EXE_LW: begin
wreg_o <= `WriteEnable; aluop_o <= `EXE_LW_OP;
alusel_o <= `EXE_RES_LOAD_STORE; reg1_read_o <= 1'b1; reg2_read_o <= 1'b0;
wd_o <= inst_i[20:16]; instvalid <= `InstValid;
end
`EXE_SW: begin
wreg_o <= `WriteDisable; aluop_o <= `EXE_SW_OP;
reg1_read_o <= 1'b1; reg2_read_o <= 1'b1; instvalid <= `InstValid;
alusel_o <= `EXE_RES_LOAD_STORE;
end
`EXE_J: begin
wreg_o <= `WriteDisable; aluop_o <= `EXE_J_OP;
alusel_o <= `EXE_RES_JUMP_BRANCH; reg1_read_o <= 1'b0; reg2_read_o <= 1'b0;
link_addr_o <= `ZeroWord;
branch_addr_o <= {pc_plus_4[31:28], inst_i[25:0], 2'b00};
branch_flag_o <= `Branch;
instvalid <= `InstValid;
end
`EXE_JAL: begin
wreg_o <= `WriteEnable;//write back 31 register
aluop_o <= `EXE_JAL_OP;
alusel_o <= `EXE_RES_JUMP_BRANCH; reg1_read_o <= 1'b0; reg2_read_o <= 1'b0;
wd_o <= 5'b11111;//save return address register
link_addr_o <= pc_plus_4 ;//return instr address
branch_addr_o <= {pc_plus_4[31:28], inst_i[25:0], 2'b00};
branch_flag_o <= `Branch;
instvalid <= `InstValid;
end
`EXE_BEQ: begin
wreg_o <= `WriteDisable; aluop_o <= `EXE_BEQ_OP;
alusel_o <= `EXE_RES_JUMP_BRANCH; reg1_read_o <= 1'b1; reg2_read_o <= 1'b1;
instvalid <= `InstValid;
if(reg1_o == reg2_o) begin
branch_addr_o <= pc_plus_4 + imm_sll2_signedext;
branch_flag_o <= `Branch;
end
end
`EXE_BNE: begin
wreg_o <= `WriteDisable; aluop_o <= `EXE_BNE_OP;
alusel_o <= `EXE_RES_JUMP_BRANCH; reg1_read_o <= 1'b1; reg2_read_o <= 1'b1;
instvalid <= `InstValid;
if(reg1_o != reg2_o) begin
branch_addr_o <= pc_plus_4 + imm_sll2_signedext;
branch_flag_o <= `Branch;
end
end
`EXE_SPECIAL2_INST: begin
case ( op3 )
`EXE_MUL: begin
wreg_o <= `WriteEnable; aluop_o <= `EXE_MUL_OP;
alusel_o <= `EXE_RES_MUL; reg1_read_o <= 1'b1; reg2_read_o <= 1'b1;
instvalid <= `InstValid;
end
default: begin
end
endcase //EXE_SPECIAL_INST2 case
end
default: begin
aluop_o <= `EXE_NOP_OP;
alusel_o <= `EXE_RES_NOP;
wd_o <= inst_i[15:11];
wreg_o <= `WriteDisable;
instvalid <= `InstValid;
reg1_read_o <= 1'b0;
reg2_read_o <= 1'b0;
reg1_addr_o <= inst_i[25:21];
reg2_addr_o <= inst_i[20:16];
imm <= 32'h0;
link_addr_o <= `ZeroWord;
inst_o <= `ZeroWord;
branch_addr_o <= `ZeroWord;
branch_flag_o <= `NotBranch;
end
endcase //case op
if (inst_i[31:21] == 11'b00000000000) begin
if (op3 == `EXE_SLL) begin
wreg_o <= `WriteEnable; aluop_o <= `EXE_SLL_OP;
alusel_o <= `EXE_RES_SHIFT; reg1_read_o <= 1'b0; reg2_read_o <= 1'b1;
imm[4:0] <= inst_i[10:6]; wd_o <= inst_i[15:11];
instvalid <= `InstValid;
end else if ( op3 == `EXE_SRL ) begin
wreg_o <= `WriteEnable; aluop_o <= `EXE_SRL_OP;
alusel_o <= `EXE_RES_SHIFT; reg1_read_o <= 1'b0; reg2_read_o <= 1'b1;
imm[4:0] <= inst_i[10:6]; wd_o <= inst_i[15:11];
instvalid <= `InstValid;
end else if ( op3 == `EXE_SRA ) begin
wreg_o <= `WriteEnable; aluop_o <= `EXE_SRA_OP;
alusel_o <= `EXE_RES_SHIFT; reg1_read_o <= 1'b0; reg2_read_o <= 1'b1;
imm[4:0] <= inst_i[10:6]; wd_o <= inst_i[15:11];
instvalid <= `InstValid;
end
end //if
end //always
always @ (*) begin
if(rst == `RstEnable) begin
reg1_o <= `ZeroWord;
end
/*else if((reg1_read_o == 1'b1) && (wreg_o == 1'b1) && (wd_o == reg1_addr_o)) begin
reg1_o <= ex_wdata_i;
end
else if((reg1_read_o == 1'b1) && (mem_wreg_i == 1'b1) && (mem_wd_i == reg1_addr_o)) begin
reg1_o <= mem_wdata_i;
end*/
else if(reg1_read_o == 1'b1) begin
reg1_o <= reg1_data_i;
end else if(reg1_read_o == 1'b0) begin
reg1_o <= imm;
end else begin
reg1_o <= `ZeroWord;
end
end
always @ (*) begin
if(rst == `RstEnable) begin
reg2_o <= `ZeroWord;
end
/*else if((reg2_read_o == 1'b1) && (wreg_o == 1'b1) && (wd_o == reg2_addr_o)) begin
reg2_o <= ex_wdata_i;
end
else if((reg2_read_o == 1'b1) && (mem_wreg_i == 1'b1) && (mem_wd_i == reg2_addr_o)) begin
reg2_o <= mem_wdata_i;
end */
else if(reg2_read_o == 1'b1) begin
reg2_o <= reg2_data_i;
end else if(reg2_read_o == 1'b0) begin
reg2_o <= imm;
end else begin
reg2_o <= `ZeroWord;
end
end
endmodule
module ex(
input wire rst,
//ID-EX input
input wire[`RegBus] link_addr_i,
input wire[`InstAddrBus] inst_i,
input wire[`AluOpBus] aluop_i,
input wire[`AluSelBus] alusel_i,
input wire[`RegBus] reg1_i,
input wire[`RegBus] reg2_i,
input wire[`RegAddrBus] wd_i,
input wire wreg_i,
//HI?LO?????
input wire[`RegBus] hi_i,
input wire[`RegBus] lo_i,
output reg[`RegBus] hi_o,
output reg[`RegBus] lo_o,
output reg whilo_o,
//EX-WB output
output reg[`AluOpBus] aluop_o,
output reg[`MemAddrBus] memaddr_o,
output reg[`MemBus] reg1data_o,
output reg[`MemBus] reg2data_o,
output reg[`RegAddrBus] wd_o,
output reg wreg_o,
output reg[`RegBus] wdata_o
);
//logic result
reg[`RegBus] logicout;
reg[`RegBus] shiftres;
reg[`RegBus] arithmeticres;
reg[`DoubleRegBus] mulres;
reg[`RegBus] HI;
reg[`RegBus] LO;
wire[`RegBus] reg2_i_mux;
wire[`RegBus] reg1_i_not;
wire[`RegBus] result_sum;
wire ov_sum;
wire[`RegBus] opdata1_mult;
wire[`RegBus] opdata2_mult;
wire[`DoubleRegBus] hilo_temp;
//LW SW mem
always @ (*) begin
//op
aluop_o <= aluop_i;
//mem_addr
memaddr_o <= reg1_i + {{16{inst_i[15]}},inst_i[15:0]};
//sw save reg2value to memaddr
reg1data_o <= reg1_i;
reg2data_o <= reg2_i;
end
always @ (*) begin
if(rst == `RstEnable) begin
logicout <= `ZeroWord;
end else begin
case (aluop_i)
`EXE_OR_OP: begin
logicout <= reg1_i | reg2_i;
end
`EXE_AND_OP: begin
logicout <= reg1_i & reg2_i;
end
`EXE_XOR_OP: begin
logicout <= reg1_i ^ reg2_i;
end
default: begin
logicout <= `ZeroWord;
end
endcase
end //if
end //always
always @ (*) begin
if(rst == `RstEnable) begin
shiftres <= `ZeroWord;
end else begin
case (aluop_i)
`EXE_SLL_OP: begin
shiftres <= reg2_i << reg1_i[4:0] ;
end
`EXE_SRL_OP: begin
shiftres <= reg2_i >> reg1_i[4:0];
end
`EXE_SRA_OP: begin
shiftres <= ({32{reg2_i[31]}} << (6'd32-{1'b0, reg1_i[4:0]}))
| reg2_i >> reg1_i[4:0];
end
default: begin
shiftres <= `ZeroWord;
end
endcase
end //if
end //always
//add?sub op2
assign reg2_i_mux = (aluop_i == `EXE_SUB_OP)
? (~reg2_i)+1 : reg2_i;
//add?sub result
assign result_sum = reg1_i + reg2_i_mux;
//overflag
assign ov_sum = ((!reg1_i[31] && !reg2_i_mux[31]) && result_sum[31]) ||
((reg1_i[31] && reg2_i_mux[31]) && (!result_sum[31]));
always @ (*) begin
if(rst == `RstEnable) begin
arithmeticres <= `ZeroWord;
end else begin
case (aluop_i)
`EXE_ADD_OP: begin
arithmeticres <= result_sum;
end
`EXE_SUB_OP: begin
arithmeticres <= result_sum;
end
default: begin
arithmeticres <= `ZeroWord;
end
endcase
end
end
//mul two op
assign opdata1_mult = (((aluop_i == `EXE_MUL_OP) || (aluop_i == `EXE_MULT_OP))
&& (reg1_i[31] == 1'b1)) ? (~reg1_i + 1) : reg1_i;
assign opdata2_mult = (((aluop_i == `EXE_MUL_OP) || (aluop_i == `EXE_MULT_OP))
&& (reg2_i[31] == 1'b1)) ? (~reg2_i + 1) : reg2_i;
//mul result
assign hilo_temp = opdata1_mult*opdata2_mult;
always @ (*) begin
if(rst == `RstEnable) begin
mulres <= {`ZeroWord,`ZeroWord};
end else if ((aluop_i == `EXE_MULT_OP) || (aluop_i == `EXE_MUL_OP))begin
if(reg1_i[31] ^ reg2_i[31] == 1'b1) begin
mulres <= ~hilo_temp + 1;
end else begin
mulres <= hilo_temp;
end
end else begin
mulres <= hilo_temp;
end
end
//ex to mem?wb
always @ (*) begin
if(rst == `RstEnable) begin
{HI,LO} <= {`ZeroWord,`ZeroWord};
end else begin
{HI,LO} <= {hi_i,lo_i};
end
end
//output
always @ (*) begin
wd_o <= wd_i;
if(((aluop_i == `EXE_ADD_OP) || (aluop_i == `EXE_ADDI_OP) ||
(aluop_i == `EXE_SUB_OP)) && (ov_sum == 1'b1)) begin
wreg_o <= `WriteDisable;
end else begin
wreg_o <= wreg_i;
end
aluop_o <= aluop_i;
reg1data_o <= reg1_i;
reg2data_o <= reg2_i;
case ( alusel_i )
`EXE_RES_LOGIC: begin
wdata_o <= logicout;
end
`EXE_RES_SHIFT: begin
wdata_o <= shiftres;
end
`EXE_RES_ARITHMETIC: begin
wdata_o <= arithmeticres;
end
`EXE_RES_MUL: begin
wdata_o <= mulres[31:0];
end
`EXE_RES_JUMP_BRANCH: begin
wdata_o <= link_addr_i;
end
default: begin
wdata_o <= `ZeroWord;
end
endcase
end
//HI _ LO
always @ (*) begin
if(rst == `RstEnable) begin
whilo_o <= `WriteDisable;
hi_o <= `ZeroWord;
lo_o <= `ZeroWord;
end else if(aluop_i == `EXE_MULT_OP||aluop_i == `EXE_MUL_OP) begin
whilo_o <= `WriteEnable;
hi_o <= mulres[63:32];
lo_o <= mulres[31:0];
end else begin
whilo_o <= `WriteDisable;
hi_o <= `ZeroWord;
lo_o <= `ZeroWord;
end
end
endmodule
module wb(
input wire rst,
//EX-WB input
input wire[`RegAddrBus] ex_wd,
input wire ex_wreg,
input wire[`RegBus] ex_wdata,
input wire[`AluOpBus] aluop_i,
input wire[`MemAddrBus] memaddr_i,
input wire[`MemBus] reg1data_i,
input wire[`MemBus] reg2data_i,
//mem-wb input
input wire[`MemBus] rmemdata_i,
//
output reg iow,
output reg ior,
//wb-Regfile output
output reg[`RegAddrBus] wb_wd,
output reg wb_wreg,
output reg[`RegBus] wb_wdata,
//wb-mem output
output reg[`MemBus] mem_wmemdata_o,
output reg[`MemAddrBus] mem_memaddr_o,
output reg mem_wmem_o,
output reg mem_rmem_o,
output reg[3:0] mem_msel_o
);
always @ (*) begin
if(rst == `RstEnable) begin
wb_wd <= `NOPRegAddr;
wb_wreg <= `WriteDisable;
wb_wdata <= `ZeroWord;
mem_memaddr_o <= `ZeroWord;
mem_wmem_o <= `WriteDisable;
mem_rmem_o <= `ReadDisable;
mem_msel_o <= 4'b0000;
mem_wmemdata_o <= `ZeroWord;
iow <= `WriteDisable;
ior <= `ReadDisable;
//mem_mce_o <= `ChipDisable;
end else begin
wb_wd <= ex_wd;
wb_wreg <= ex_wreg;
wb_wdata <= ex_wdata;
mem_memaddr_o <= `ZeroWord;
mem_wmem_o <= `WriteDisable;
mem_rmem_o <= `ReadDisable;
mem_msel_o <= 4'b1111;
mem_wmemdata_o <= `ZeroWord;
//mem_mce_o <= `ChipDisable;
iow <= `WriteDisable;
ior <= `ReadDisable;
case (aluop_i)
`EXE_LW_OP: begin
mem_rmem_o <= ((memaddr_i & `IOBase)!=`IOBase)?1:0;
ior <= ((memaddr_i & `IOBase)==`IOBase)?1:0;
if(ior == `ReadEnable) begin
mem_memaddr_o <= memaddr_i;
// mem_rmem_o <= `ReadEnable;
wb_wdata <= rmemdata_i;
// mem_mce_o <= `ChipEnable;
end else if (mem_rmem_o == `ReadEnable) begin
mem_memaddr_o <= memaddr_i;
// mem_rmem_o <= `ReadEnable;
wb_wdata <= rmemdata_i;
// mem_mce_o <= `ChipEnable;
end
end
`EXE_SW_OP: begin
mem_wmem_o <= ((memaddr_i & `IOBase)!=`IOBase)?1:0;
iow <= ((memaddr_i & `IOBase)==`IOBase)?1:0;
if(iow == `WriteEnable)begin
mem_memaddr_o <= memaddr_i;
// mem_wmem_o <= `WriteEnable;
mem_wmemdata_o <= reg2data_i;
end else if(mem_wmem_o == `WriteEnable) begin
mem_memaddr_o <= memaddr_i;
// mem_wmem_o <= `WriteEnable;
mem_wmemdata_o <= reg2data_i;
// mem_mce_o <= `ChipEnable;
end
end
default: begin
//?????
end
endcase
end //if
end //always
endmodule
//mem-io
module MIOC(
input wire rst,
//wb to mioc input
input wire ior_i,
input wire iow_i,
output reg [`MemBus] rm_idata_o,
input wire [`MemBus] wm_idata_i,
input wire [`MemAddrBus] m_iaddr_i,
input wire mw_i,
input wire mr_i,
input wire [3:0] msel_i,
//MIOC to Mem output
input wire[`MemBus] rmdata_i,
output reg [`MemBus] wmdata_o,
output reg [`MemAddrBus] maddr_o,
output reg memw_o,
output reg mce_o,
output reg [3:0] msel_o,
//MIOC to IO output
output reg [`IOBus] wiodata_o,
input wire [`IOBus] riodata_i,
output reg iow_o,
output reg ice_o,
output reg [`IOAddrBus] ioaddr_o
);
always @ (*) begin
if(rst == `RstEnable) begin
//output to wb
rm_idata_o <= `ZeroWord;
wmdata_o <= `ZeroWord;
maddr_o <= `ZeroWord;
memw_o <= `WriteDisable;
mce_o <= `ChipDisable;
msel_o <= 4'b0000;
wiodata_o <= `ZeroWord;
iow_o <= `WriteDisable;
ice_o <= `ChipDisable;
ioaddr_o <= `ZeroWord;
end else begin
if(ior_i == `ReadEnable) begin
rm_idata_o <= riodata_i;
iow_o <= `WriteDisable;
ice_o <= `ChipEnable;
ioaddr_o <= m_iaddr_i;
end else if (iow_i == `WriteEnable) begin
ioaddr_o <= m_iaddr_i;
iow_o <= `WriteEnable;
ice_o <= `ReadEnable;
wiodata_o <= wm_idata_i;
end else if(mr_i == `ReadEnable)begin
rm_idata_o <= rmdata_i;
maddr_o <= m_iaddr_i;
memw_o <= `WriteDisable;
mce_o <= `ChipEnable;
msel_o <= 4'b1111;
end else if(mw_i == `WriteEnable) begin
maddr_o <= m_iaddr_i;
memw_o <= `WriteEnable;
wmdata_o <= wm_idata_i;
mce_o <= `ChipEnable;
msel_o <= 4'b1111;
end
end //if
end //always
endmodule
module IO(
//MIOC to IO input
input wire [`IOAddrBus] addr_i,
input wire ce_i,
input wire iow_i,
output reg [`IOBus] rdata_o,
input wire [`IOBus] wdata_i,
input wire clk,
input wire rst,
input wire [`KeyBus] key,//0xFFFFF008
input wire [`RegBus] Button,//0xFFFFF00c
output reg [`SEGBus] SEG,//0xFFFFF000
output reg [`KeyBus] LED//0xFFFFF004
);
//IO model
reg [`IOBus] IO [`IONum-1:0];
always@(posedge clk)
begin
if(rst == `RstEnable) begin
LED <= `ZeroWord;
SEG <= `ZeroWord;
end else begin
case(addr_i)
`LED_ADDR: begin
LED <= wdata_i[15:0];
end
`SEG_ADDR: begin
SEG <= wdata_i;
end
endcase
end
end
always@(*)
begin
if(ce_i == `ChipDisable) begin
rdata_o <= `ZeroWord;
end else begin
case(addr_i)
`KEY_ADDR: begin
rdata_o <= {{16{1'b0}},key};
//rdata_o <= 32'hffff000f;
end
`BUTTON_ADDR: begin
//rdata_o <= Button;
rdata_o <= 32'hffffffff;
end
endcase
end
end
endmodule
顶层模块Prep_DEMO.v
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 10:50:10 11/03/2014
// Design Name:
// Module Name: Output_2_Disp
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module Prep_IO(input wire clk_100mhz,
// I/O:
input wire[15:0]SW,
//input wire OPENMIPS_rst;
output wire led_clk,
output wire led_clrn,
output wire led_sout,
output wire LED_PEN,
output wire seg_clk,
output wire seg_clrn,
output wire seg_sout,
output wire SEG_PEN,
output Buzzer
);
wire [31:0] Div;
wire CK;
wire [15:0] LedData;
wire [31:0] pc_1;
wire [31:0] rom_output_data;
wire rom_ena;
assign Buzzer = 1;
wire [15:0] key;
wire [31:0] SEG;
wire [15:0] LED;
wire[63:0] disp_data;
assign LedData = ~LED;
assign key = SW;
clk_div U8(clk_100mhz,1'b0,SW[0],Div,CK);
P2S #(.DATA_BITS(64),.DATA_COUNT_BITS(6))
P7SEG (clk_100mhz,
1'b0,
Div[20],
disp_data,
seg_clk,
seg_clrn,
seg_sout,
SEG_PEN
);
LED_P2S #(.DATA_BITS(16),.DATA_COUNT_BITS(4))
PLED (clk_100mhz,
1'b0,
Div[20],
LedData,
led_clk,
led_clrn,
led_sout,
LED_PEN
);
BCD bcd(.in(SEG),.out(disp_data));
OpenMIPS OPEN01(.rst(SW[15]),.clk(CK),.rom_data_i(rom_output_data),
.rom_addr_o(pc_1),.rom_ce_o(rom_ena),.key(key),.SEG(SEG),.LED(LED));
inst_rom(.ce(rom_ena),.addr(pc_1),.inst(rom_output_data));
//rom01 rom0001(.clka(CK),.ena(rom_ena),.addra(pc_1),.douta(rom_output_data));
endmodule
运行效果:
方案一 使用FPGA模型机在FPGA开发板上进行按键输入输出测试
方案二 使用FPGA模型机在FPGA开发板上进行流水灯测试
测试分析与结论
根据上述测试数据,验证模型机在FPGA开发板上执行的正确性以及先前在modelsim上进行开发的所有过程、所有指令的准确性的测试,测试结果表明:FPGA模型机可以在实验箱上,实现正确IO端口操作,以及使用FPGA模型机设计的指令,进行了流水灯的设计,验证了系统开发的可行性与准确性,最终获得了模型机开发圆满结束。