MIPS指令的CPU实现:ALU设计
2021-05-29 16:27
465 查看
设计CPU的第一步,设计一个简单的逻辑运算单元ALU。
使用Vivado软件编程,利用FPGA开发板NEXYS,同时对Verilog语言也有一定要求。
一、实验内容
- 如图,ALU接受两个N位的输入,得到N位的输出,通过控制信号F决定运算功能。
- 将ALU的输出结构与七段数码管显示模块连接,使用实验配置的NEXYS4开发板。
结构如下:
- 编写顶层模块top连接上述模块。
- 仿真,编写约束文件,生成二进制文件,在开发板上验证。
整体难度不大,主要任务就是编写ALU和top,以及约束文件。
但是这学期之前在摸鱼,这个小实验都没认真弄好。。。地基打不好,CPU肯定写不出来啊。
二、RTL级的部分Verilog代码,也是重点部分
ALU.v
真的很简单,方法两种,一种是always逻辑,一种是assign逻辑。
- always:
module ALU( input wire [31:0] A, input wire[31:0] B, input wire [2:0] OP, // 输入用wire output reg [31:0] F //输出用寄存器reg ); always @(*) begin case(OP) 3'b000: begin F <= A + B; end //这里实际上连进位都没有考虑 3'b001: begin F <= A - B; end 3'b010: begin F <= A & B; end 3'b011: begin F <= A | B; end 3'b100: begin F <= ~A; end 3'b101: begin F <= A<B; end default: begin F <= 0; end endcase end endmodule
- assign:
assign相当于连线,一般是将一个变量的值不间断地赋值给另一个变量,所以赋值的类型应用wire。
module ALU( input wire [31:0] A, input wire[31:0] B, input wire [2:0] OP, output wire [31:0] F ); assign F = (OP == 3'b000) ? A + B: (OP == 3'b001) ? A - B: (OP == 3'b010) ? A & B: (OP == 3'b011) ? A | B: (OP == 3'b100) ? ~A: (OP == 3'b101) ? A < B: 32'b0; endmodule
数码管显示模块display.v和seg7.v(实验提供)
- display.v
module display( input wire clk,reset, input wire [31:0]s, output wire [6:0]seg, output reg [7:0]ans ); reg [20:0]count; reg [4:0]digit; always@(posedge clk,posedge reset) if(reset) count = 0; else count = count + 1; always @(posedge clk) case(count[20:18]) 0:begin ans = 8'b11111110; digit = s[3:0]; end 1:begin ans = 8'b11111101; digit = s[7:4]; end 2:begin ans = 8'b11111011; digit =s[11:8]; end 3:begin ans = 8'b11110111; digit = s[15:12]; end 4:begin ans = 8'b11101111; digit = s[19:16]; end 5:begin ans = 8'b11011111; 56c digit = s[23:20]; end 6:begin ans = 8'b10111111; digit =s[27:24]; end 7:begin ans = 8'b01111111; digit = s[31:28]; end endcase seg7 U4(.din(digit),.dout(seg)); endmodule
- seg7.v
module seg7( input wire [3:0]din, output reg [6:0]dout ); always@(*) case(din) 5'h0:dout = 7'b000_0001; 5'h1:dout = 7'b100_1111; 5'h2:dout = 7'b001_0010; 5'h3:dout = 7'b000_0110; 5'h4:dout = 7'b100_1100; 5'h5:dout = 7'b010_0100; 5'h6:dout = 7'b010_0000; 5'h7:dout = 7'b000_1111; 5'h8:dout = 7'b000_0000; 5'h9:dout = 7'b000_0100; 5'ha:dout = 7'b000_1000; 5'hb:dout = 7'b110_0000; 5'hc:dout = 7'b011_0001; 5'hd:dout = 7'b100_0010; 5'he:dout = 7'b011_0000; 5'hf:dout = 7'b011_1000; default:dout = 7'b111_1111; endcase endmodule
top.v
module top( input wire clk, rst, output wire[6:0] seg, output wire[7:0] ans, input wire [2:0] op, input wire [7:0] num_1 ); wire [31:0] f; // f从ALU传给display ALU U1(.A({24'b0,num_1}),.B(32'h1),.OP 56c (op),.F(f)); // 输入a为8位扩充至32位,b为固定值32'h1 display U2(.clk(clk),.reset(rst),.s(f),.ans(ans),.seg(seg)); endmodule
三、存在的问题
- 仿真测试中得不到结果,但是下到板子上以后能正常运行
仿真的 testbench 文件:
module test(); reg [7:0] num_1; reg [2:0] op; wire [6:0]seg; wire [7:0]ans; reg clk,rst; always #25 clk = ~clk; initial begin clk = 1; rst = 0; num_1 = 8'h 11; op = 3'b 111; # 100 op = 3'b 000; # 100 op = 3'b 001; # 100 op = 3'b 010; # 100 op = 3'b 011; # 100 op = 3'b 100; # 100 op = 3'b 101; end top x( .clk(clk), .rst(rst), .seg(seg), .ans(ans), .num_1(num_1), .op(op) ); endmodule
程序写入开发板:
相关文章推荐
- 杭电计算机组成原理课程设计-实验十三-实现R-I-J型指令的CPU设计实验
- 自己动手写CPU之第九阶段(5)——实现加载存储指令4(修改OpenMIPS顶层模块)
- Verilog实现单周期CPU(部分MIPS指令集的指令)
- 设计一个简易的处理器(3)--SEQ CPU的实现(1): 将指令组织成阶段
- MIPS单周期CPU设计(24条指令)
- MIPS多周期CPU设计之使用时钟上升沿触发PC模块的实现方案
- 杭电计算机组成原理课程设计-实验十一-实现R型指令的CPU设计实验
- 杭电计算机组成原理课程设计-实验十二-实现R-I型指令的CPU设计实验
- Atitit 计算机系统结构 计算机系统结构 Cpu 存储 cache 指令系统 目录 Line 56: 第2章指令系统设计 指令格式 寻址方式 1 Line 64: 第3章CPU及其实现
- Linux 的 Spinlock 在 MIPS 多核处理器中的设计与实现
- CPU性能衡量参数-主频,MIPS,CPI,时钟周期,机器周期,指令周期
- 计算机组成原理实验 单总线CPU设计(变长指令周期3级时序)(HUST)思路总结
- MIPS-单周期CPU设计
- Linux 的 Spinlock 在 MIPS 多核处理器中的设计与实现
- [计算机组成原理][实验十.R-I-J型指令CPU设计实验总结]
- 自己动手写CPU之第九阶段(5)——实现加载存储指令1(修改译码阶段)
- 计算机组成原理实验 单总线CPU设计(定长指令周期3级时序)(HUST)思路总结
- Verilog实现IMPS的5级流水线cpu设计(Modelsim仿真)
- 自己动手写CPU之第四阶段(2)——验证第一条指令ori的实现效果
- 自己动手写CPU之第六阶段(4)——验证移动操作指令实现效果