Week3:本周学习的知识主要包括:Verilog的基本语法知识以及一个简单的RISC处理器的硬件组成,并使用Verilog描述了各个硬件模块的功能。
内容回顾
Verilog语法的几点回顾
- 逻辑操作和位宽操作
- logic operation: a && b、a || b、!c
- Bit-wise operation: a&b、a|b、~c
- 逻辑移位和算术移位
- logic shift: a >> 1, a is unsigned
- arithmetic shift: a >>> 1, a is signed
- 位宽划分
- a[7-:4] = a[7:4] = a[4+:4]
- signed 补码 、unsigned 原码
由于之前上过Verilog的语法课,因此以上知识点只是整理了我认为比较重要的几处,更多的Verilog语法请参考以下链接
一个简单的RISC硬件组成
麻雀虽小,五脏俱全。根据冯诺依曼理论,一个计算机包括存储器、运算器、控制器以及输入输出设备。该节介绍的极简RISC硬件也具有这些,当然不包括输入输出设备。下面将用Verilog去实现这些硬件电路,完成一个简单的RISC处理器。
存储器 (Memory)
- 寄存器列表(RF)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36module regfile #(
parameter REG_DATA_WIDTH = 4,
parameter REG_ADDR_WIDTH = 16,
parameter REG_NUMBER = 16
)
(
input [REG_ADDR_WIDTH-1:0] rs1_addr,
input [REG_ADDR_WIDTH-1:0] rs2_addr,
input [REG_ADDR_WIDTH-1:0] rd_addr,
input [REG_DATA_WIDTH-1:0] rd_data,
input RegWEn,
input clk,rst_n,
output [REG_DATA_WIDTH-1:0] rs1_data,
output [REG_DATA_WIDTH-1:0] rs2_data
);
reg [REG_DATA_WIDTH-1:0] rf [REG_NUMBER-1:0];
// reg0 is always equal to zero
assign rs1_data = rs1_addr == 0? 0:rf[rs1_addr];
assign rs2_data = rs2_addr == 0? 0:rf[rs2_addr];
always@ (posedge clk or negedge rst_n) begin
if (!rst_n) begin: REGFILE
integer i;
for (i=0; i<REG_NUMBER; i=i+1) begin
rf[i] <= 0;
end
end
else if (RegWEn && rd_addr!=0) begin
rf[rd_addr] <= rd_data;
end
end
endmodule - 数据存储器(DCM)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25module dcmen #(
parameter MEM_ADDR_WIDTH = 5,
parameter MEM_DATA_WIDTH = 16,
parameter MEM_NUMBER = 32
)
(
input clk,
input MemWEn,
input [MEM_ADDR_WIDTH-1:0] addr,
input [MEM_DATA_WIDTH-1:0] dataw,
output [MEM_DATA_WIDTH-1:0] datar
);
reg [MEM_DATA_WIDTH-1:0]RAM [MEM_NUMBER-1:0];
always @(posedge clk) begin
if (MemWEn) begin
RAM[addr] <= dataw;
end
end
assign datar = RAM[addr] ;
endmodule - 指令存储器(ICM)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41module icmem #(
parameter PC_WIDTH = 16,
parameter ISA_WIDTH = 16,
parameter MEM_ADDR_WIDTH = 5,
parameter MEM_DATA_WIDTH = 16,
parameter MEM_NUMBER = 32
)
(
input clk,
input rst_n,
input inst_wen,
input [ISA_WIDTH-1:0] input_inst,
output [ISA_WIDTH-1:0] current_inst
);
reg [PC_WIDTH-1:0] pc;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
// reset
pc <= 0;
end
else begin
pc <= pc + 1;
end
end
dcmen #(
.MEM_ADDR_WIDTH(MEM_ADDR_WIDTH),
.MEM_DATA_WIDTH(MEM_DATA_WIDTH),
.MEM_NUMBER(MEM_NUMBER)
) inst_dcmen (
.clk (clk),
.MemWEn (inst_wen),
.addr (pc),
.dataw (input_inst),
.datar (current_inst)
);
endmodule
运算器 (ALU)
1 | module MAC_ALU #( |
关于Verilog语法中*的使用,可以参考以下链接
控制器 (IDU)
1 |
极简指令集与其硬件组成
| opcode | 目标Reg | 源寄存器/立即数 | 说明 |
|---|---|---|---|
| Load | rd | rs+imm(5b) | 在rst imm地址 -> rd |
| Store | / | rs(addr)/rs(data) | rs(data) -> Mem index=rs(地址) |
| MOV | rd | imm(9b) | 赋值 -> rd |
| MAC | rd | rs1/funct=1 | 乘加 |
| MAC | rd | rs1/funct=1 | 乘加 |
注明:不同颜色的数据通路对应其相同颜色的指令
