实验十二 寄存器及寄存器堆
姓名:
学号:
专业:
工科试验班
课程名称:
逻辑与计算机设计基础
同组学生姓名:
无
实验时间:
2009年12月23日
实验地点:
紫金港东4-509
指导老师:
蒋方炎
一、实验目的和要求
1、掌握寄存器、锁存器的工作原理及设计方法
2、掌握寄存器堆的工作原理及设计方法
3、了解计算机中寄存器及寄存器堆的概念
二、实验内容和原理
2.1 寄存器
寄存器是由若干个触发器并联采用同一个时钟或使能信号构成的器件.一般采用边沿触发来暂存数据.用实验六边沿D触发器构成的8位寄存器如图1所示.所有的触发器采用同一个时钟信号置数和同一个时复位信号清除.
实现8位寄存器的代码如下所示。
module register(clk, D, clear, Q );
input clk,clear;
input [7:0]D;
output [7:0]Q;
wire [7:0]Qbar;
reg S=1;
initial S <= 1'b1;
assign cr = ~clear;
BUFG cc(clk1, clk);
D_flop_posedge R0(clk1, D[0], cr, S, Q[0], Qbar[0]),
R1(clk1, D[1], cr, S, Q[1], Qbar[1]),
R2(clk1, D[2], cr, S, Q[2], Qbar[2]),
R3(clk1, D[3], cr, S, Q[3], Qbar[3]),
R4(clk1, D[4], cr, S, Q[4], Qbar[4]),
R5(clk1, D[5], cr, S, Q[5], Qbar[5]),
R6(clk1, D[6], cr, S, Q[6], Qbar[6]),
R7(clk1, D[7], cr, S, Q[7], Qbar[7]);
endmodule
2.2 锁存器
这里指的锁存是1位锁存器单元线性阵列,只要用来锁定输入数据,并给后续逻辑电路提供持续的信号。与寄存器类似,可以用若干个1位锁存器或者触发器并联而成,一般采用电平控制锁存。当使能端的高电平置入数据,低电平锁存并指示数据稳定,如图2所示。
采用带使能端的RS触发器可以方便地实现锁存器。其代码如下所示。
module lock(lock, D, clear, Q);
input lock,clear;
input [7:0]D;
output [7:0]Q;
wire [7:0] Qbar;
wire [7:0]cr,Din;
assign cr = {8{clear}} | (~D);
assign Din = D & (~{8{clear}});
assign lock1 = lock | clear;
RS_CE R0(lock1, cr[0], Din[0], Q[0], Qbar[0]),
R1(lock1, cr[1], Din[1], Q[1], Qbar[1]),
R2(lock1, cr[2], Din[2], Q[2], Qbar[2]),
R3(lock1, cr[3], Din[3], Q[3], Qbar[3]),
R4(lock1, cr[4], Din[4], Q[4], Qbar[4]),
R5(lock1, cr[5], Din[5], Q[5], Qbar[5]),
R6(lock1, cr[6], Din[6], Q[6], Qbar[6]),
R7(lock1, cr[7], Din[7], Q[7], Qbar[7]);
endmodule
2.3 寄存器组
寄存器组(register files)是多个寄存器组成的一个集合。在集合的输入、输出端加上读写控制就可以实现寄存器组。寄存器组写入电路要确定是从那个寄存器读出,可有数据选择器来实现,寄存器地址作为控制端,如图3所示。
其代码如下所示:
module register_file(clk, cr, Address, Di, Do);
input clk,cr;
input [2:0]Address;
input [31:0]Di;
output [31:0]Do;
reg CE=0;
wire [31:0]Do0, Do1, Do2, Do3, Do4, Do5, Do6, Do7;
wire [7:0]Y,Yi;
wire [2:0]SEL;
wire [2:0]Address;
initial CE <= 0;
assign SEL = Address;
assign Y = ~Yi;
assign CLK = {8{clk}} && Y;
register_32 rr0(CLK[0], Di, cr, Do0 );
register_32 rr1(CLK[1], Di, cr, Do1 );
register_32 rr2(CLK[2], Di, cr, Do2 );
register_32 rr3(CLK[3], Di, cr, Do3 );
register_32 rr4(CLK[4], Di, cr, Do4 );
register_32 rr5(CLK[5], Di, cr, Do5 );
register_32 rr6(CLK[6], Di, cr, Do6 );
register_32 rr7(CLK[7], Di, cr, Do7 );
decode_3_8 d(Address[2], Address[1], Address[0], CE, Yi);
MUX_8_1 mux(SEL, Do0, Do1, Do2, Do3, Do4, Do5, Do6, Do7, Do);
endmodule
module register_32(cl, Di, cr, Dot);
input cl,cr;
input [31:0]Di;
output [31:0]Dot;
reg[31:0]Dot;
BUFG cck(cck,cl);
always @(posedge cl)
Dot <= (!cr) ? 0 : Di;
endmodule
三、主要仪器设备
1. 实验设备
(a)装有ISE的计算机系统 1台
(b)Spartan-III 开发板 1套
2. 实验材料
无
四、操作方法与实验步骤
4.1 实验要求
实现含由4个8位寄存器构成的寄存器堆,要求:
1、支持寄存器地址选择
2、支持写入任意8位值
3、支持读取寄存器的值
4.2 Verilog代码
module top992(clk, led, digit_anode, segment, switch, btn);
input wire clk;
input wire [7:0]switch;
input wire [3:0]btn;
output wire [3:0]digit_anode;
output wire [7:0]segment;
output wire [3:0]led;
wire [3:0]Yi;
wire clk0,clk1,clk2,clk3;
wire [7:0]regQ0, regQ1, regQ2, regQ3;
wire [7:0]SelQ;
assign led[3:0] = btn[3:0];
assign clk0 = clk & Yi[0];
assign clk1 = clk & Yi[1];
assign clk2 = clk & Yi[2];
assign clk3 = clk & Yi[3];
decode_2_4 M0(btn[1], btn[0], btn[3], Yi);
mux_4_1 M1(btn[1], btn[0], btn[2], regQ0, regQ1, regQ2, regQ3, SelQ);
display M2(clk, {switch[7:0],SelQ[7:0]}, digit_anode, segment);
register8 R0(clk0, switch, regQ0),
R1(clk1, switch, regQ1),
R2(clk2, switch, regQ2),
R3(clk3, switch, regQ3);
endmodule
module decode_2_4(A, B, G, Yi);
input wire A, B, G;
output wire [3:0] Yi;
not n0(A_n, A),
n1(B_n, B);
and a0(Yi[0], G, A_n, B_n),
a1(Yi[1], G, A_n, B),
a2(Yi[2], G, A, B_n),
a3(Yi[3], G, A, B);
endmodule
module mux_4_1 (a, b, c,regQ0, regQ1, regQ2, regQ3, SelQ);
input wire a,b,c;
input wire [7:0]regQ0,regQ1,regQ2,regQ3;
output [7:0]SelQ;
reg [7:0]SelQ;
wire [7:0]tn;
assign tn={c,c,c,c,c,c,c,c};
always@(posedge c)
begin
case ({a,b})
2'b00:SelQ<=regQ0&tn;
2'b01:SelQ<=regQ1&tn;
2'b10:SelQ<=regQ2&tn;
2'b11:SelQ<=regQ3&tn;
endcase
end
endmodule
module register8 (clk,sw,re);
input wire clk;
input wire [7:0]sw;
output wire [7:0]re;
FD RO(.C(clk),.D(sw[0]),.Q(re[0])),
R1(.C(clk),.D(sw[1]),.Q(re[1])),
R2(.C(clk),.D(sw[2]),.Q(re[2])),
R3(.C(clk),.D(sw[3]),.Q(re[3])),
R4(.C(clk),.D(sw[4]),.Q(re[4])),
R5(.C(clk),.D(sw[5]),.Q(re[5])),
R6(.C(clk),.D(sw[6]),.Q(re[6])),
R7(.C(clk),.D(sw[7]),.Q(re[7]));
endmodule
module display(clk,digit,digit_anode, segment);
input clk;
input wire [15:0] digit;
output reg [3:0] digit_anode;
output reg [ 7:0] segment;
reg [3:0] code = 4'b0;
reg [15:0] count = 15'b0;
always @(posedge clk) begin
case (count[15:14])
2'b00 : begin
digit_anode <= 4'b1110;
code <= digit[3:0];
end
2'b01 : begin
digit_anode <= 4'b1101;
code <= digit[7:4];
end
2'b10 : begin
digit_anode <= 4'b1011;
code <= digit[11:8];
end
2'b11 : begin
digit_anode <= 4'b0111;
code <= digit[15:12];
end
endcase
case (code)
4'b0000: segment <= 8'b11000000;
4'b0001: segment <= 8'b11111001;
4'b0010: segment <= 8'b10100100;
4'b0011: segment <= 8'b10110000;
4'b0100: segment <= 8'b10011001;
4'b0101: segment <= 8'b10010010;
4'b0110: segment <= 8'b10000010;
4'b0111: segment <= 8'b11111000;
4'b1000: segment <= 8'b10000000;
4'b1001: segment <= 8'b10010000;
4'b1010: segment <= 8'b10001000;
4'b1011: segment <= 8'b10000011;
4'b1100: segment <= 8'b11000110;
4'b1101: segment <= 8'b10100001;
4'b1110: segment <= 8'b10000110;
4'b1111: segment <= 8'b10001110;
default: segment <= 8'b00000000;
endcase
count <= count + 1;
end
endmodule
4.3 UCF引脚
net "clk" loc = "T9";
net "segment[0]" loc = "E14";
net "segment[1]" loc = "G13";
net "segment[2]" loc = "N15";
net "segment[3]" loc = "P15";
net "segment[4]" loc = "R16";
net "segment[5]" loc = "F13";
net "segment[6]" loc = "N16";
net "segment[7]" loc = "P16";
net "digit_anode[0]" loc = "D14";
net "digit_anode[1]" loc = "G14";
net "digit_anode[2]" loc = "F14";
net "digit_anode[3]" loc = "E13";
net "btn[0]" loc = "M13";
net "btn[1]" loc = "M14";
net "btn[2]" loc = "L13";
net "btn[3]" loc = "L14";
net "btn[0]" clock_dedicated_route = false;
net "btn[1]" clock_dedicated_route = false;
net "btn[2]" clock_dedicated_route = false;
net "btn[3]" clock_dedicated_route = false;
net "switch[0]" loc= "F12";
net "switch[1]" loc= "G12";
net "switch[2]" loc= "H14";
net "switch[3]" loc= "H13";
net "switch[4]" loc= "J14";
net "switch[5]" loc= "J13";
net "switch[6]" loc= "K14";
net "switch[7]" loc= "K13";
net "led[0]" loc ="K12";
net "led[1]" loc ="L12";
net "led[2]" loc ="P13";
net "led[3]" loc ="P12";
五、实验结果与
上图是我用自己电脑运行上述代码所得的运行结果。
在实验室其实现了如下功能:
左边2个按键作为寄存器堆的地址输入,右边2个按键分别作为读使能、写使能;并将4个按键的值显示在4个LED上
将8个拨动开关作为寄存器堆的数据输入,同时将数据显示在左边2个七段数码管上
读寄存器时,结果显示在右边2个七段数码管上。
它很好的实现上述功能,最后通过老师检验。
六、讨论、心得
第8页/共8页