在此项目中,Verilog HDL中实现了16位单周期MIPS处理器。 MIPS 是一个 RISC处理器,已被许多大学广泛用于与计算机组织和架构相关的学术课程。
指令格式和 指令集架构 16位单周期MIPS的情况如下:
![]() |
MIPS 处理器的指令集 |
![]() |
MIPS 处理器的指令集架构 |
以下是在Verilog中实现的说明的说明:
- 加:R [rd] = R [rs] + R [rt]
- 减:R [rd] = R [rs]-R [rt]
- 并且:R [rd] = R [rs]& R[rt]
- 或:R [rd] = R [rs] | R [rt]
- SLT: 如果R [rs],则R [rd] = 1< R[rt] 否则0
- Jr:PC = R [rs]
- Lw:R [rt] = M [R [rs] + SignExtImm]
- Sw:M [R [rs] + SignExtImm] = R [rt]
- Beq:if(R [rs] == R [rt])PC = PC + 1 + 科 Addr
- Addi:R [rt] = R [rs] + SignExtImm
- : PC = 跳 Addr
- Jal:R [7] = PC + 2; PC = 跳 Addr
- SLTI: 如果R [rs],则R [rt] = 1< 嗯 else 0
SignExtImm = {9 {immediate [6]},imm
跳 Addr = {(PC + 1)[15:13],地址}
科 Addr = {7 {immediate [6]},立即,1’b0 }
根据提供的指令集,设计并实现数据路径和控制单元。
控制单元设计:
控制信号
| |||||||||
指令
|
注册
Dst
|
ALUSrc
|
门托
注册
|
注册
写
|
记忆读
|
m
写
|
科
|
铝
|
跳
|
R型
|
1
|
0
|
0
|
1
|
0
|
0
|
0
|
00
|
0
|
轻量级
|
0
|
1
|
1
|
1
|
1
|
0
|
0
|
11
|
0
|
西南
|
0
|
1
|
0
|
0
|
0
|
1
|
0
|
11
|
0
|
阿迪
|
0
|
1
|
0
|
1
|
0
|
0
|
0
|
11
|
0
|
贝克
|
0
|
0
|
0
|
0
|
0
|
0
|
1
|
01
|
0
|
j
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
00
|
1
|
贾尔
|
2
|
0
|
2
|
1
|
0
|
0
|
0
|
00
|
1
|
ti
|
0
|
1
|
0
|
1
|
0
|
0
|
0
|
10
|
0
|
ALU控制
| ||||
ALU op
|
功能
|
铝
|
ALU操作
|
指令
|
11
|
xxx
|
000
|
加
|
Addi,lw,sw
|
01
|
xxx
|
001
|
潜艇
|
BEQ
|
00
|
00
|
000
|
加
|
R型:ADD
|
00
|
01
|
001
|
潜艇
|
R型:子
|
00
|
02
|
010
|
和
|
R型:与
|
00
|
03
|
011
|
要么
|
R型:或
|
00
|
04
|
100
|
slt
|
R型:SLT
|
10
|
xxx xx
|
100
|
slt
|
i型:slti
|
![]() |
16位MIPS处理器的数据路径和控制单元 |
完成MIPS处理器的设计后,可以很容易地为MIPS处理器编写Verilog代码。用于MIPS处理器整个设计的Verilog代码如下:
ALU单元的Verilog代码
寄存器文件的Verilog代码
指令存储器的Verilog代码
通过在ModelSim或Xilinx ISIM上进行几次仿真来验证MIPS处理器的工作原理,验证单周期MIPS CPU的Verilog代码非常简单。为了完全验证MIPS处理器,需要修改指令存储器以模拟指令集体系结构中的所有指令,然后检查模拟波形和存储器以查看处理器是否按设计正常工作。
您可能会这样:
Verilog中的32位5级流水线MIPS处理器(第1部分)
Verilog中的32位5级流水线MIPS处理器(第2部分)
Verilog中的32位5级流水线MIPS处理器(第3部分)
16位RISC处理器的Verilog代码
MIPS 处理器的VHDL代码
29。 复用器的Verilog代码
寄存器文件的Verilog代码
指令存储器的Verilog代码
数据存储器的Verilog代码:
//hzgifts.cn: FPGA projects, Verilog projects, VHDL projects // Verilog project: Verilog code for 16-bit MIPS Processor // Submodule: Data memory in Verilog module data_memory ( input clk, // address input, shared by read and write 港口 input [15:0] mem_access_addr, // write 港口 input [15:0] mem_write_data, input mem_write_en, input mem_read, // read 港口 output [15:0] mem_read_data ); integer i; reg [15:0] ram [255:0]; wire [7 : 0] ram_addr = mem_access_addr[8 : 1]; initial begin for(i=0;i<256;i=i+1) ram[i] <= 16'd0; 结束 always @(posedge clk) begin if (mem_write_en) ram[ram_addr] <= mem_write_data; 结束 assign mem_read_data = (mem_read==1'b1) ? ram[ram_addr]: 16'd0; 终端模块
ALU控制单元的Verilog代码:
//hzgifts.cn: FPGA projects, Verilog projects, VHDL projects // Verilog project: Verilog code for 16-bit MIPS Processor // Submodule: ALU控制 Unit in Verilog module ALUControl( ALU_Control, 铝 , 功能 ); output reg[2:0] ALU_Control; input [1:0] 铝 ; input [3:0] 功能 ; wire [5:0] ALUControlIn; assign ALUControlIn = {ALUOp,Function}; always @(ALUControlIn) casex (ALUControlIn) 6'b11 xxx : ALU_Control=3'b000; 6'b10 xxx : ALU_Control=3'b100; 6'b01 xxx : ALU_Control=3'b001; 6'b000000: ALU_Control=3'b000; 6'b000001: ALU_Control=3'b001; 6'b000010: ALU_Control=3'b010; 6'b000011: ALU_Control=3'b011; 6'b000100: ALU_Control=3'b100; default: ALU_Control=3'b000; 结束 case 终端模块 // Verilog code for JR control unit module JR_Control( input[1:0] alu_op, input [3:0] funct, output JRControl ); assign JRControl = ({alu_op,funct}==6'b001000) ? 1'b1 : 1'b0; 终端模块
控制单元的Verilog代码:
//hzgifts.cn: FPGA projects, Verilog projects, VHDL projects // Verilog project: Verilog code for 16-bit MIPS Processor // Submodule: Control Unit in Verilog module control( input[2:0] opcode, input reset, output reg[1:0] reg_dst,mem_to_reg,alu_op, output reg jump,branch,mem_read,mem_write,alu_src,reg_write,sign_or_zero ); always @(*) begin if(reset == 1'b1) begin reg_dst = 2'b00; mem_to_reg = 2'b00; alu_op = 2'b00; jump = 1'b0; branch = 1'b0; mem_read = 1'b0; mem_write = 1'b0; alu_src = 1'b0; reg_write = 1'b0; sign_or_zero = 1'b1; 结束 else begin case(opcode) 3'b000: begin // add reg_dst = 2'b01; mem_to_reg = 2'b00; alu_op = 2'b00; jump = 1'b0; branch = 1'b0; mem_read = 1'b0; mem_write = 1'b0; alu_src = 1'b0; reg_write = 1'b1; sign_or_zero = 1'b1; 结束 3'b001: begin // sli reg_dst = 2'b00; mem_to_reg = 2'b00; alu_op = 2'b10; jump = 1'b0; branch = 1'b0; mem_read = 1'b0; mem_write = 1'b0; alu_src = 1'b1; reg_write = 1'b1; sign_or_zero = 1'b0; 结束 3'b010: begin // j reg_dst = 2'b00; mem_to_reg = 2'b00; alu_op = 2'b00; jump = 1'b1; branch = 1'b0; mem_read = 1'b0; mem_write = 1'b0; alu_src = 1'b0; reg_write = 1'b0; sign_or_zero = 1'b1; 结束 3'b011: begin // 贾尔 reg_dst = 2'b10; mem_to_reg = 2'b10; alu_op = 2'b00; jump = 1'b1; branch = 1'b0; mem_read = 1'b0; mem_write = 1'b0; alu_src = 1'b0; reg_write = 1'b1; sign_or_zero = 1'b1; 结束 3'b100: begin // lw reg_dst = 2'b00; mem_to_reg = 2'b01; alu_op = 2'b11; jump = 1'b0; branch = 1'b0; mem_read = 1'b1; mem_write = 1'b0; alu_src = 1'b1; reg_write = 1'b1; sign_or_zero = 1'b1; 结束 3'b101: begin // sw reg_dst = 2'b00; mem_to_reg = 2'b00; alu_op = 2'b11; jump = 1'b0; branch = 1'b0; mem_read = 1'b0; mem_write = 1'b1; alu_src = 1'b1; reg_write = 1'b0; sign_or_zero = 1'b1; 结束 3'b110: begin // 贝克 reg_dst = 2'b00; mem_to_reg = 2'b00; alu_op = 2'b01; jump = 1'b0; branch = 1'b1; mem_read = 1'b0; mem_write = 1'b0; alu_src = 1'b0; reg_write = 1'b0; sign_or_zero = 1'b1; 结束 3'b111: begin // 阿迪 reg_dst = 2'b00; mem_to_reg = 2'b00; alu_op = 2'b11; jump = 1'b0; branch = 1'b0; mem_read = 1'b0; mem_write = 1'b0; alu_src = 1'b1; reg_write = 1'b1; sign_or_zero = 1'b1; 结束 default: begin reg_dst = 2'b01; mem_to_reg = 2'b00; alu_op = 2'b00; jump = 1'b0; branch = 1'b0; mem_read = 1'b0; mem_write = 1'b0; alu_src = 1'b0; reg_write = 1'b1; sign_or_zero = 1'b1; 结束 结束 case 结束 结束 终端模块
单周期的Verilog代码 MIPS 处理器:
//hzgifts.cn: FPGA projects, Verilog projects, VHDL projects // Verilog project: Verilog code for 16-bit MIPS Processor // Verilog code for 16 bit single cycle MIPS CPU module mips_16( input clk,reset, output[15:0] pc_out, alu_result //,reg3,reg4 ); reg[15:0] pc_current; wire signed[15:0] pc_next,pc2; wire [15:0] instr; wire[1:0] reg_dst,mem_to_reg,alu_op; wire jump,branch,mem_read,mem_write,alu_src,reg_write ; wire [2:0] reg_write_dest; wire [15:0] reg_write_data; wire [2:0] reg_read_addr_1; wire [15:0] reg_read_data_1; wire [2:0] reg_read_addr_2; wire [15:0] reg_read_data_2; wire [15:0] sign_ext_im,read_data2,zero_ext_im,imm_ext; wire JRControl; wire [2:0] ALU_Control; wire [15:0] ALU_out; wire zero_flag; wire signed[15:0] im_shift_1, PC_j, PC_beq, PC_4beq,PC_4beqj,PC_jr; wire 贝克 _control; wire [14:0] jump_shift_1; wire [15:0]mem_read_data; wire [15:0] no_sign_ext; wire sign_or_zero; // PC always @(posedge clk or posedge reset) begin if(reset) pc_current <= 16'd0; else pc_current <= pc_next; 结束 // PC + 2 assign pc2 = pc_current + 16'd2; // instruction memory instr_mem instrucion_memory(.pc(pc_current),.instruction(instr)); // jump shift left 1 assign jump_shift_1 = {instr[13:0],1'b0}; // control unit control control_unit(.reset(reset),.opcode(instr[15:13]),.reg_dst(reg_dst) ,.mem_to_reg(mem_to_reg),.alu_op(alu_op),.jump(jump),.branch(branch),.mem_read(mem_read), .mem_write(mem_write),.alu_src(alu_src),.reg_write(reg_write),.sign_or_zero(sign_or_zero)); // multiplexer regdest assign reg_write_dest = (reg_dst==2'b10) ? 3'b111: ((reg_dst==2'b01) ? instr[6:4] :instr[9:7]); // register file assign reg_read_addr_1 = instr[12:10]; assign reg_read_addr_2 = instr[9:7]; register_file reg_file(.clk(clk),.rst(reset),.reg_write_en(reg_write), .reg_write_dest(reg_write_dest), .reg_write_data(reg_write_data), .reg_read_addr_1(reg_read_addr_1), .reg_read_data_1(reg_read_data_1), .reg_read_addr_2(reg_read_addr_2), .reg_read_data_2(reg_read_data_2)); //.reg3(reg3), //.reg4(reg4)); // sign extend assign sign_ext_im = {{9{instr[6]}},instr[6:0]}; assign zero_ext_im = {{9{1'b0}},instr[6:0]}; assign 嗯 _ext = (sign_or_zero==1'b1) ? sign_ext_im : zero_ext_im; // JR control JR_Control JRControl_unit(.alu_op(alu_op),.funct(instr[3:0]),.JRControl(JRControl)); // ALU control unit ALUControl ALU_Control_unit(.ALUOp(alu_op),.Function(instr[3:0]),.ALU_Control(ALU_Control)); // multiplexer alu_src assign read_data2 = (alu_src==1'b1) ? 嗯 _ext : reg_read_data_2; // ALU alu alu_unit(.a(reg_read_data_1),.b(read_data2),.alu_control(ALU_Control),.result(ALU_out),.zero(zero_flag)); // 嗯 ediate shift 1 assign im_shift_1 = {imm_ext[14:0],1'b0}; // assign no_sign_ext = ~(im_shift_1) + 1'b1; // PC 贝克 add assign PC_beq = (im_shift_1[15] == 1'b1) ? (pc2 - no_sign_ext): (pc2 +im_shift_1); // 贝克 control assign 贝克 _control = branch & zero_flag; // PC_beq assign PC_4beq = (beq_control==1'b1) ? PC_beq : pc2; // PC_j assign PC_j = {pc2[15],jump_shift_1}; // PC_4beqj assign PC_4beqj = (jump == 1'b1) ? PC_j : PC_4beq; // PC_jr assign PC_jr = reg_read_data_1; // PC_next assign pc_next = (JRControl==1'b1) ? PC_jr : PC_4beqj; // data memory data_memory datamem(.clk(clk),.mem_access_addr(ALU_out), .mem_write_data(reg_read_data_2),.mem_write_en(mem_write),.mem_read(mem_read), .mem_read_data(mem_read_data)); // write back assign reg_write_data = (mem_to_reg == 2'b10) ? pc2:((mem_to_reg == 2'b01)? mem_read_data: ALU_out); // output assign pc_out = pc_current; assign alu_result = ALU_out; 终端模块
单周期MIPS处理器的Verilog测试平台代码:
`timescale 1ns / 1ps //hzgifts.cn: FPGA projects, Verilog projects, VHDL projects // Verilog project: Verilog code for 16-bit MIPS Processor // Testbench Verilog code for 16 bit single cycle MIPS CPU module tb_mips16; // Inputs reg clk; reg reset; // Outputs wire [15:0] pc_out; wire [15:0] alu_result;//,reg3,reg4; // Instantiate the Unit Under Test (UUT) mips_16 uut ( .clk(clk), .reset(reset), .pc_out(pc_out), .alu_result(alu_result) //.reg3(reg3), // .reg4(reg4) ); initial begin clk = 0; forever #10 clk = ~clk; 结束 initial begin // Initialize Inputs //$monitor ("register 3=%d, register 4=%d", reg3,reg4); reset = 1; // Wait 100 ns for global reset to finish #100; reset = 0; // Add stimulus here 结束 终端模块
源代码提供者
阿卜杜拉萨克·穆罕默德·阿纳纳
阿卜杜拉萨克·穆罕默德·阿纳纳
Verilog中的32位5级流水线MIPS处理器(第1部分)
Verilog中的32位5级流水线MIPS处理器(第2部分)
Verilog中的32位5级流水线MIPS处理器(第3部分)
16位RISC处理器的Verilog代码
MIPS 处理器的VHDL代码
推荐的 Verilog projects:
2. FIFO存储器的Verilog代码
3. 用于16位单周期MIPS处理器的Verilog代码
4. Verilog HDL中的可编程数字延迟计时器
5. 用于数字电路中基本逻辑组件的Verilog代码
6. 用于32位无符号除法器的Verilog代码
7. 用于定点矩阵乘法的Verilog代码
8. Verilog HDL中的车牌许可证识别
9. 提前进位乘法器的Verilog代码
10。 微处理器的Verilog代码
11。 4x4乘法器的Verilog代码
12 停车场系统的Verilog代码
13 使用Verilog HDL在FPGA上进行图像处理
14。 如何使用Verilog HDL将文本文件加载到FPGA中
15 交通信号灯控制器的Verilog代码
16。 FPGA上的闹钟的Verilog代码
17。 比较器设计的Verilog代码
18岁 D触发器的Verilog代码
19 Full Adder的Verilog代码
20 带testbench的计数器的Verilog代码
21 16位RISC处理器的Verilog代码
22 用于在FPGA上反跳按钮的Verilog代码
23。 如何为双向/输入端口编写Verilog Testbench
3. 用于16位单周期MIPS处理器的Verilog代码
4. Verilog HDL中的可编程数字延迟计时器
5. 用于数字电路中基本逻辑组件的Verilog代码
6. 用于32位无符号除法器的Verilog代码
7. 用于定点矩阵乘法的Verilog代码
8. Verilog HDL中的车牌许可证识别
9. 提前进位乘法器的Verilog代码
10。 微处理器的Verilog代码
11。 4x4乘法器的Verilog代码
12 停车场系统的Verilog代码
13 使用Verilog HDL在FPGA上进行图像处理
14。 如何使用Verilog HDL将文本文件加载到FPGA中
15 交通信号灯控制器的Verilog代码
16。 FPGA上的闹钟的Verilog代码
17。 比较器设计的Verilog代码
18岁 D触发器的Verilog代码
19 Full Adder的Verilog代码
20 带testbench的计数器的Verilog代码
21 16位RISC处理器的Verilog代码
22 用于在FPGA上反跳按钮的Verilog代码
23。 如何为双向/输入端口编写Verilog Testbench
24 Verilog和LogiSim中的Tic Tac Toe游戏
25岁 Verilog中的32位5级流水线MIPS处理器(第1部分)
26 Verilog中的32位5级流水线MIPS处理器(第2部分)
27。 Verilog中的32位5级流水线MIPS处理器(第3部分)
28。 解码器的Verilog代码25岁 Verilog中的32位5级流水线MIPS处理器(第1部分)
26 Verilog中的32位5级流水线MIPS处理器(第2部分)
27。 Verilog中的32位5级流水线MIPS处理器(第3部分)
29。 复用器的Verilog代码
30岁 Verilog中的N位加法器设计
我可以和您一起检查一下我必须在试验台代码中包括哪种类型的刺激。我用测试台运行了整个程序100ns,但寄存器值为0或x
回复 删除您如何应用刺激
删除仔细检查您的指令存储器。此处的所有说明均已完全验证。
回复 删除您可以按指令检查指令,并查看寄存器文件,数据存储器以进行验证。
好的,谢谢您的建议。我还有另一个问题,当我编译程序时,出现以下错误:
回复 删除错误(12006):节点实例"JR_Control_unit"实例化未定义的实体"JR_Control"
有人知道如何解决吗?
模块JR_Control(input [1:0] alu_op,
回复 删除输入[3:0]功能,
输出JRControl
);
分配JRControl =({alu_op,funct} == 6'b001000) ? 1'b1 : 1'b0;
终端模块
这里是
非常感谢你的帮助!
删除什么是
删除港口' ' reg 3 ' ' is not a 港口of reg_file
港口' ' reg 4 ' ' is not a 港口of reg_file
在mips_16_bit模块中
如何在MIPS处理器中实现流水线结构?我是否只是在各个阶段之间实施注册?如果是这样,我在哪里实现它们。
回复 删除即将在Verilog中发布管道式MIPS。
回复 删除谁能解释一下工作原理,我将非常感激..plz
回复 删除我收到错误:
回复 删除港口' ' reg 3 ' ' is not a 港口of reg_file
港口' ' reg 4 ' ' is not a 港口of reg_file
有什么帮助吗? :-)
`时标1ns / 1ps
回复 删除模块register_file
( //hzgifts.cn: FPga projects, Verilog projects, VHDL projects
输入clk
输入第一个
// write 港口
输入reg_write_en,
输入[2:0] reg_write_dest,
输入[15:0] reg_write_data,
//read 港口1
输入[2:0] reg_read_addr_1,
输出[15:0] reg_read_data_1,
//read 港口2
输入[2:0] reg_read_addr_2,
输出[15:0] reg_read_data_2
);
reg [15:0] reg_array [7:0];
// write 港口
// reg [2:0] i;
总是@(posege clk或posege rst)开始
如果开始
reg_array [0]<= 15'b0;
reg_array [1]<= 15'b0;
reg_array [2]<= 15'b0;
reg_array [3]<= 15'b0;
reg_array [4]<= 15'b0;
reg_array [5]<= 15'b0;
reg_array [6]<= 15'b0;
reg_array [7]<= 15'b0;
结束
否则开始
if(reg_write_en)开始
reg_array [reg_write_dest]<= reg_write_data;
结束
结束
结束
分配reg_read_data_1 =(reg_read_addr_1 == 0)? 15'b0:reg_array [reg_read_addr_1];
分配reg_read_data_2 =(reg_read_addr_2 == 0)? 15'b0:reg_array [reg_read_addr_2];
终端模块
我试过了,但最终输出只是输出'z's ???我想我不知道这里应该发生什么
删除请发布带有数据路径和控制单元说明的32位流水线risc处理器的Verilog代码
回复 删除http://www.hzgifts.cn/2017/06/32-bit-pipelined-mips-processor-in-verilog-1.html
删除http://www.hzgifts.cn/2017/06/32-bit-pipelined-mips-processor-in-verilog-2.html
http://www.hzgifts.cn/2017/06/32-bit-pipelined-mips-processor-in-verilog-3.html
请检查一下用于32位流水线处理器的Verilog代码
港口' ' reg 3 ' ' is not a 港口of reg_file
回复 删除港口' ' reg 4 ' ' is not a 港口of reg_file
那'仅用于仿真调试。
删除您可以轻松添加reg3 = reg_array [3]或reg4 = reg_array [4]。
如果您不这样做,则可以在顶级代码中将其注释掉'不想在仿真中看到它。
http://www.hzgifts.cn/2017/06/32-bit-pipelined-mips-processor-in-verilog-1.html
回复 删除http://www.hzgifts.cn/2017/06/32-bit-pipelined-mips-processor-in-verilog-2.html
http://www.hzgifts.cn/2017/06/32-bit-pipelined-mips-processor-in-verilog-3.html
请检查一下用于32位流水线处理器的Verilog代码
先生,16位MIPS的JR_Control代码在哪里?
回复 删除在ALU控制单元中更新。谢谢。
删除16位风险和16位mips处理器之间有什么区别。我读到mips是基于风险的处理器!
回复 删除我已经在帖子中提到过,MIPS是RISC处理器。
删除我有一个问题"电线[7:0] ram_addr = mem_access_addr [9:2];" in the data memory.
回复 删除Isn'每个字存储一个16位吗?我认为可以写成"电线[7:0] ram_addr = mem_access_addr [7:0];。只需一个存储字即可对齐MIPS数据访问单元。
感谢您的提问。它是一个16位CPU,因此每个字2个字节。 PC和偏移地址增加2。因此ram_addr = mem_access_addr [8:1]或rom_addr = PC [4:1]。
删除如果使用导线[7:0] ram_addr = mem_access_addr [7:0],则将省略奇数地址(1、3、5、7等)。
可编程优先编码器的Verilog代码?
回复 删除感谢您的建议。
删除我将所有文件都移到了quartus上,但是如何测试呢?
回复 删除有人可以为单周期MIPS处理器(32位)发布3 STAGE verilog代码吗
回复 删除我可以实现这个代码是iverilog吗?
回复 删除因为如果使用循环,编译器将错误显示为无法理解的循环。
请提供使用Verilog设计基于MIPS的单周期(32位)处理器的代码,以获取有关R型(ADD,SUB,AND,OR,SLT),I / M型(LW / 西南 )的指令/ 加 I / 潜艇 I)和BEQ和J型
回复 删除说明(JAL,J)。仅考虑整数类型的操作。
如何增加刺激?
回复 删除你好
回复 删除在RTL级别上,此代码正确给出了结果,但是在合成该代码时却给出了错误。任何想法如何解决这个问题?
有谁能够对此进行后期合成模拟。
谢谢。
请问alu_unit和instruction_memory如何共享代码?
回复 删除所有代码都共享,这两个链接也都在帖子中共享。
删除