Verilog仿真——双向寄存器74HC194

任务

实现双向寄存器74HC194的程序设计与仿真

时序电路的仿真

  • 多使用行为级建模:always@( )
  • 与组合逻辑电路对高低电平敏感相比,时序电路对电平变化敏感
    • 使用关键词posedge与negedge,分别代表上升沿敏感与下降沿敏感
    • 通常支持同时将电平敏感事件和边沿敏感事件列写在always@( )中

示例:D触发器

代码设计

//filename:trigger.v
module Dff(
	input D,CL,
	output reg Q,Q_n
);
always@(posedge CL)begin
	Q=D;
	Q_n=~D;
end
endmodule

仿真

//filename:tb_trigger.v
`timescale 1ns/1ns
module tb_trigger;
reg D,CL;
wire Q,Q_n;
//实例化D触发器
Dff Dff_inst(
.D(D),
.CL(CL),
.Q(Q),
.Q_n(Q_n)
);
initial
	CL=1'b0;
always
	#1 CL=~CL;
initial begin
	#1
	D=0;
	#1
	D=0;
	#1
	D=0;
	#1
	D=1;
	#1
	D=1;
	#1
	D=1;
	#1
	$stop;
end
endmodule

重点是时钟信号的产生:

initial
	CL=1'b0;
always
	#1 CL=~CL;

将CL首先设置为低电平,通过always语句每隔1个时间尺度timescale翻转1次

程序设计

DSR端是右移串行数据输入端,DSL是左移串行数据输入端~CR为异步清零输入端。
表中第一行表示寄存器异步清零操作;第二行为保持状态; 第三、四行为串行数据右移操作;第五、六行为串行数据的左移操作;第七行为并行数据同步置数操作。原文链接

时序电路采用<=

//filename:74HC194.v
module register_194(
	input CR_n,S1,S0,CP,DSR,DSL,
	input [3:0] D,
	output reg [3:0] Q
);
/*功能描述
双向移位寄存器74HC194
*/
/*端口描述
DSR:右移串行数据输入端
DSL:左移串行数据输入端
CR_n:异步清零输入端
CP:时钟信号
S1,S0:控制信号
D:预置输入数据
Q:输出数据
*/
always@(negedge CR_n,posedge CP)begin
	if(~CR_n)
	//异步清零
	Q<=4'h0;
	else if(CP)begin
	//否则检测是否是时钟上升沿触发
		if(~S1&&S0)
		//右移数据
		Q<={DSR,Q[3:1]};
		else if(S1&&~S0)
		//左移数据
		Q<={Q[2:0],DSL};
		else if(S1&&S0)
		//预置输入数据
		Q<=D;
	end
end
endmodule

仿真

//filename:tb_74HC194.v
`timescale 1ns/1ns
module tb_74HC194;
reg CR_n,S1,S0,CP,DSR,DSL;
reg [3:0] D;
wire [3:0] Q;
//实例化
register_194 register_194_inst(
.CR_n(CR_n),
.S1(S1),
.S0(S0),
.CP(CP),
.DSR(DSR),
.DSL(DSL),
.D(D),
.Q(Q)
);
//时钟脉冲
initial
	CP=0;
always
	#1 CP=~CP;
//测试
initial begin
	//预置为1111
	CR_n=1;S1=1;S0=1;DSR=0;DSL=0;D=4'b1111;
	#2
	//清零
	CR_n=0;S1=1;S0=1;DSR=0;DSL=0;D=4'b1111;
	#2
	//右移,DSR=1
	CR_n=1;S1=0;S0=1;DSR=1;DSL=0;D=4'b1111;
	#2
	//右移,DSR=1
	CR_n=1;S1=0;S0=1;DSR=1;DSL=0;D=4'b1111;
	#2
	//右移,DSR=0
	CR_n=1;S1=0;S0=1;DSR=0;DSL=0;D=4'b1111;
	#2
	//右移,DSR=0
	CR_n=1;S1=0;S0=1;DSR=0;DSL=0;D=4'b1111;
	#2
	//清零
	CR_n=0;S1=1;S0=1;DSR=0;DSL=0;D=4'b1111;
	#2
	//左移,DSL=1
	CR_n=1;S1=1;S0=0;DSR=0;DSL=1;D=4'b1111;
	#2
	//左移,DSL=1
	CR_n=1;S1=1;S0=0;DSR=0;DSL=1;D=4'b1111;
	#2
	//左移,DSL=0
	CR_n=1;S1=1;S0=0;DSR=0;DSL=0;D=4'b1111;
	#2
	//左移,DSL=0
	CR_n=1;S1=1;S0=0;DSR=0;DSL=0;D=4'b1111;
	#2
	$stop;
end
endmodule

1 comment

Leave a comment

Your email address will not be published. Required fields are marked *