注:相应的源文件在文末的github链接中
实验七 寄存器堆的设计和实现
一.实验要求
1、设计由16个4位寄存器构成的寄存器堆,该寄存器堆是双端口输出。进行功能仿真
2、设计由16个4位寄存器构成的寄存器堆,引脚绑定后进行下载,在EGO1开发板上进行数据验证。
二.设计含有16个4位寄存器的寄存器堆,该寄存器堆同时有两个地址输入raddr1和raddr2,对应的两个输出为rdata1和rdata2。
源文件
//3.2.1 desgin文件
module top (
input clk, //寄存器组时钟信号,下降沿写入数据
input rst, //异步复位信号,高电平时全部寄存器置零
input we, //寄存器读写有效信号,低电平时允许寄存器写入数据,
//高电平时允许寄存器读出数据
input[3:0] raddr1, //所需读取的寄存器的地址
input[3:0] raddr2, //所需读取的寄存器的地址
input[3:0] waddr, //写寄存器的地址
input[3: 0] wdata, //写寄存器数据,数据在clk下降沿时被写入
output[3: 0] rdata1, //raddr1所对应寄存器的输出数据
output[3: 0] rdata2 //raddr2所对应寄存器的输出数据
);
// 实例化decode模块
wire [15:0] addr_dec;
decoder_4to16 dec(.a(waddr), .en(we), .d(addr_dec));
wire [3:0] reg_outs [15:0];//定义一个4x4的二维 wire 数组
// 实例化16个寄存器模块
regfils reg1 (.clk(clk), .rst(rst), .enb(addr_dec[0]), .din(wdata), .dout(reg_outs[0]));
regfils reg2 (.clk(clk), .rst(rst), .enb(addr_dec[1]), .din(wdata), .dout(reg_outs[1]));
regfils reg3 (.clk(clk), .rst(rst), .enb(addr_dec[2]), .din(wdata), .dout(reg_outs[2]));
regfils reg4 (.clk(clk), .rst(rst), .enb(addr_dec[3]), .din(wdata), .dout(reg_outs[3]));
regfils reg5 (.clk(clk), .rst(rst), .enb(addr_dec[4]), .din(wdata), .dout(reg_outs[4]));
regfils reg6 (.clk(clk), .rst(rst), .enb(addr_dec[5]), .din(wdata), .dout(reg_outs[5]));
regfils reg7 (.clk(clk), .rst(rst), .enb(addr_dec[6]), .din(wdata), .dout(reg_outs[6]));
regfils reg8 (.clk(clk), .rst(rst), .enb(addr_dec[7]), .din(wdata), .dout(reg_outs[7]));
regfils reg9 (.clk(clk), .rst(rst), .enb(addr_dec[8]), .din(wdata), .dout(reg_outs[8]));
regfils reg10 (.clk(clk), .rst(rst), .enb(addr_dec[9]), .din(wdata), .dout(reg_outs[9]));
regfils reg11 (.clk(clk), .rst(rst), .enb(addr_dec[10]), .din(wdata), .dout(reg_outs[10]));
regfils reg12 (.clk(clk), .rst(rst), .enb(addr_dec[11]), .din(wdata), .dout(reg_outs[11]));
regfils reg13 (.clk(clk), .rst(rst), .enb(addr_dec[12]), .din(wdata), .dout(reg_outs[12]));
regfils reg14 (.clk(clk), .rst(rst), .enb(addr_dec[13]), .din(wdata), .dout(reg_outs[13]));
regfils reg15 (.clk(clk), .rst(rst), .enb(addr_dec[14]), .din(wdata), .dout(reg_outs[14]));
regfils reg16 (.clk(clk), .rst(rst), .enb(addr_dec[15]), .din(wdata), .dout(reg_outs[15]));
// 实例化选择器模块并连接输入
//4选1数据选择器
selector_16to1 sel1(
.D_0(reg_outs[0]),
.D_1(reg_outs[1]),
.D_2(reg_outs[2]),
.D_3(reg_outs[3]),
.D_4(reg_outs[4]),
.D_5(reg_outs[5]),
.D_6(reg_outs[6]),
.D_7(reg_outs[7]),
.D_8(reg_outs[8]),
.D_9(reg_outs[9]),
.D_10(reg_outs[10]),
.D_11(reg_outs[11]),
.D_12(reg_outs[12]),
.D_13(reg_outs[13]),
.D_14(reg_outs[14]),
.D_15(reg_outs[15]),
.S(raddr1),
.en(~we),
.SOUT(rdata1)
);
selector_16to1 sel2(
.D_0(reg_outs[0]),
.D_1(reg_outs[1]),
.D_2(reg_outs[2]),
.D_3(reg_outs[3]),
.D_4(reg_outs[4]),
.D_5(reg_outs[5]),
.D_6(reg_outs[6]),
.D_7(reg_outs[7]),
.D_8(reg_outs[8]),
.D_9(reg_outs[9]),
.D_10(reg_outs[10]),
.D_11(reg_outs[11]),
.D_12(reg_outs[12]),
.D_13(reg_outs[13]),
.D_14(reg_outs[14]),
.D_15(reg_outs[15]),
.S(raddr2),
.en(~we),
.SOUT(rdata2)
);
Endmodule
激励文件(注意可能需要改变延时时间为自己的学号)
module top_tb;
reg clk;
reg rst;
reg we;
reg[3:0] raddr1;
reg[3:0] raddr2;
reg[3:0] waddr;
reg[3:0] wdata;
wire[3: 0] rdata1;
wire[3: 0] rdata2;
top top(
.clk(clk),
.rst(rst),
.we(we),
.raddr1(raddr1),
.raddr2(raddr2),
.waddr(waddr),
.wdata(wdata),
.rdata1(rdata1),
.rdata2(rdata2)
);
initial begin
clk = 1'b0;
we = 1'b0;
rst = 1'b0;
waddr = 4'b0000;
wdata = 4'b1111;
#100
clk = ~clk;
#100
clk = ~clk;
waddr = 4'b0001;
wdata = 4'b1001;
#100
clk = ~clk;
#100
clk = ~clk;
waddr = 4'b0010;
wdata = 4'b0010;
#100
clk = ~clk;
#100
clk = ~clk;
waddr = 4'b0011;
wdata = 4'b0010;
#100
clk = ~clk;
#100
clk = ~clk;
waddr = 4'b0100;
wdata = 4'b0100;
#100
clk = ~clk;
#100
clk = ~clk;
waddr = 4'b0101;
wdata = 4'b0110;
#100
clk = ~clk;
#100
clk = ~clk;
waddr = 4'b0110;
wdata = 4'b0010;
#100
clk = ~clk;
#100
clk = ~clk;
waddr = 4'b0111;
wdata = 4'b0010;
#100
clk = ~clk;
#100
clk = ~clk;
waddr = 4'b1000;
wdata = 4'b0100;
#100
clk = ~clk;
#100
clk = ~clk;
waddr = 4'b1001;
wdata = 4'b0110;
#100
clk = ~clk;
#100
clk = ~clk;
waddr = 4'b1010;
wdata = 4'b0110;
#100
clk = ~clk;
#100
clk = ~clk;
waddr = 4'b1011;
wdata = 4'b1010;
#100
clk = ~clk;
#100
clk = ~clk;
waddr = 4'b1100;
wdata = 4'b0010;
#100
clk = ~clk;
waddr = 4'b1101;
wdata = 4'b0110;
#100
clk = ~clk;
#100
clk = ~clk;
waddr = 4'b1110;
wdata = 4'b0000;
#100
clk = ~clk;
#100
clk = ~clk;
waddr = 4'b1111;
wdata = 4'b1110;
#10;
we = 1'b1;
raddr1 = 4'b0000;
#100
raddr2 = 4'b0001;
#100
raddr1 = 4'b0010;
#100
raddr2 = 4'b0011;
#100
raddr1 = 4'b0100;
#100
raddr2 = 4'b0101;
we = 1'b1;
raddr1 = 4'b0110;
#100
raddr2 = 4'b0111;
#100
raddr1 = 4'b1000;
#100
raddr2 = 4'b1001;
#100
raddr1 = 4'b1010;
#100
raddr2 = 4'b1011;
we = 1'b1;
raddr1 = 4'b1100;
#100
raddr2 = 4'b1101;
#100
raddr1 = 4'b1110;
#100
raddr2 = 4'b1111;
#100
rst = 1'b1;
end
always #25 clk <= ~clk;
endmodule
激励图像
约束文件
如果将输入输出信号与EGO1开发板上的外设进行绑定,对应绑定关系如下表7.1。下载后,在开发板上进行数据验证。对地址为0000到1111单元依次赋值1111~0000,然后在读控制信号的作用下,读出地址为0011和1010这两个4位寄存器的值。观察输出信号对应的LED灯的显示是否正确。
表7.1 输入输出信号与开发板上外设对应关系
信号 | 引脚 | 说明 |
raddr1[3:0] | sw3~sw0 | 用4个开关的值对应于读地址1 |
raddr2[3:0] | sw7~sw4 | 用另外4个开关的值对应于读地址2 |
waddr[3:0] | sw11~sw8 | 用4个开关的值对应于写地址 |
wdata[3:0] | sw15~sw12 | 用另外4个开关的值对应于要写的数据 |
rdata1[3:0] | led[3:0] | 用4个发光管的值对应于读出的数据1 |
rdata2[3:0] | led[7:4] | 用另外4个发光管的值对应于读出的数据2 |
we | s1 | 用通用按键s1(按下为1)对应于读写控制信号we |
下载后,拨动开关,观察LED灯亮灭情况,填写下表:
地址 | LED灯对应的数值 | 说明 |
0011 | ||
0110 | ||
1000 | ||
1010 |
set_property -dict {PACKAGE_PIN R2 IOSTANDARD LVCMOS33} [get_ports {raddr1[0]}]
set_property -dict {PACKAGE_PIN M4 IOSTANDARD LVCMOS33} [get_ports {raddr1[1]}]
set_property -dict {PACKAGE_PIN N4 IOSTANDARD LVCMOS33} [get_ports {raddr1[2]}]
set_property -dict {PACKAGE_PIN R1 IOSTANDARD LVCMOS33} [get_ports {raddr1[3]}]
set_property -dict {PACKAGE_PIN P5 IOSTANDARD LVCMOS33} [get_ports {raddr2[0]}]
set_property -dict {PACKAGE_PIN P4 IOSTANDARD LVCMOS33} [get_ports {raddr2[1]}]
set_property -dict {PACKAGE_PIN P3 IOSTANDARD LVCMOS33} [get_ports {raddr2[2]}]
set_property -dict {PACKAGE_PIN P2 IOSTANDARD LVCMOS33} [get_ports {raddr2[3]}]
set_property -dict {PACKAGE_PIN V4 IOSTANDARD LVCMOS33} [get_ports {waddr[0]}]
set_property -dict {PACKAGE_PIN R3 IOSTANDARD LVCMOS33} [get_ports {waddr[1]}]
set_property -dict {PACKAGE_PIN T3 IOSTANDARD LVCMOS33} [get_ports {waddr[2]}]
set_property -dict {PACKAGE_PIN T5 IOSTANDARD LVCMOS33} [get_ports {waddr[3]}]
set_property -dict {PACKAGE_PIN U3 IOSTANDARD LVCMOS33} [get_ports {wdata[0]}]
set_property -dict {PACKAGE_PIN U2 IOSTANDARD LVCMOS33} [get_ports {wdata[1]}]
set_property -dict {PACKAGE_PIN V2 IOSTANDARD LVCMOS33} [get_ports {wdata[2]}]
set_property -dict {PACKAGE_PIN V5 IOSTANDARD LVCMOS33} [get_ports {wdata[3]}]
set_property -dict {PACKAGE_PIN K6 IOSTANDARD LVCMOS33} [get_ports {rdata1[0]}]
set_property -dict {PACKAGE_PIN L1 IOSTANDARD LVCMOS33} [get_ports {rdata1[1]}]
set_property -dict {PACKAGE_PIN M1 IOSTANDARD LVCMOS33} [get_ports {rdata1[2]}]
set_property -dict {PACKAGE_PIN K3 IOSTANDARD LVCMOS33} [get_ports {rdata1[3]}]
set_property -dict {PACKAGE_PIN K1 IOSTANDARD LVCMOS33} [get_ports {rdata2[0]}]
set_property -dict {PACKAGE_PIN H6 IOSTANDARD LVCMOS33} [get_ports {rdata2[1]}]
set_property -dict {PACKAGE_PIN H5 IOSTANDARD LVCMOS33} [get_ports {rdata2[2]}]
set_property -dict {PACKAGE_PIN J5 IOSTANDARD LVCMOS33} [get_ports {rdata2[3]}]
set_property -dict {PACKAGE_PIN R11 IOSTANDARD LVCMOS33} [get_ports {rst}]
set_property -dict {PACKAGE_PIN R17 IOSTANDARD LVCMOS33} [get_ports {we}]
set_property -dict {PACKAGE_PIN P17 IOSTANDARD LVCMOS33} [get_ports {clk}]