没想到吧[滑稽]
简报
啊哈哈,一定有人觉着这个系列会终止。然而,没有写时序的笔者又岂是会随意咕咕的[doge]。下面,笔者将要用Verilog HDL在Vivado环境下对74ls194的功能进行实现!咕咕!
引脚
众所周知,74ls194是时序电路里面应用广泛的通用多功能寄存器。其本体共有1+1+1+1+2+4+2+4=16根引脚。其中,电源(Vcc)和接地(GND)没有特殊功能,下面对另外十四根引脚的功能进行说明。
- 时钟引脚(clk):共1根,接时钟信号。
- 异步清零引脚(CR):共1根,实现清零功能,当~CR=1,即CR=0时,所有触发器被清零(置0),由于不受时钟影响,被认为是异步清零。
- 控制引脚(S1,S0):共2根,在时钟信号上升沿,控制引脚的不同值实现对输入数据的不同处理(保持:00,左移:10,右移:01,输入:11)。
- 数据输入引脚(D,C,B,A):共4根,输入待处理的数据。
- 左移串入引脚(DSL):共1根,对数据进行左移处理时,拼接在左三位数据的左侧。
- 右移串入引脚(DSR)共1根,对数据进行右移处理时,拼接在右三位数据的右侧。
Tips:左移和右移串入引脚的作用方式可理解为:输入数据为六位二进制,排列顺序自高位向低位为:DSL,D,C,B,A,DSR,在此基础上进行“移位”操作。 - 数据输出引脚(QD,QC,QB,QA):共4根,输出处理后的数据。
代码
以下为74ls194的代码及部分说明。
module x74x194(
input clk,
input CR,
input A,B,C,D,
input DR,DL,
input [1:0] S,
output reg [3:0] Q=0
);
always@ (posedge clk or posedge CR)//在时钟上升沿或者CR上升沿触发功能
begin
if(~CR) //~CR为真时,各触发器置0;清零操作与时钟无关。
Q=4'b0;
else if(~clk) //当时钟信号为低电平时,移位寄存器处于保持状态。
Q=Q;
case(S)
2'b11:
Q<={D,C,B,A}; //S的值为两位二进制11时,Q接受并行输入数据DCBA。
2'b01:
Q<={Q[2:0],DR}; //S的值为两位二进制01时,数据进行右移。
2'b10:
Q<={DL,Q[3:1]}; //S的值为两位二进制10时,数据进行左移。
2'b00:
Q<=Q; //S的值为两位二进制00时,移位寄存器处于保持状态。
default:Q<={A,B,C,D}; //默认,用来骗编译器,防止出现锁存。
endcase
end
endmodule
在代码的第9行我们可以发现,模块的“启动条件”为clk或者CR进入上升沿。这里就要提醒各位刚刚接触到Verilog HDL的小白们了,我们都知道,时序逻辑电路是由具有记忆电路状态能力的储存电路和具有逻辑运算功能的组合逻辑电路组成的,但这并不意味着使用Verilog编写的代码中必须有组合逻辑模块和时序逻辑模块。因为当两个模块中的等号左侧可能发生同时对同一值进行赋值的情况时,就会出现端口存在多重驱动的情况,就像这样:
[Synth 8-6859] multi-driven net on pin RCO_OBUF with 1st driver pin 'RCO_reg__0/Q'
并且这个问题的标识为“critical warning”,因此我们应当尽力避免这种情况的发生。于是,我们选择在CR上升沿启动功能同时避免启动时钟上升沿时启动的功能(好绕啊=_=)的方式来将两模块合并,从而消除多重驱动的情况。不要问笔者是怎么知道这件事情的,问就是笔者太菜了←_←……
下面为74ls194在Verilog HDL中的仿真文件。
module SIM;
reg clk;
reg CR;
reg D,C,B,A;
reg DR,DL;
reg [1:0] S;
wire [3:0] Q;
x74x194 u1(clk,CR,D,C,B,A,DR,DL,S,Q);
initial begin
clk=0;
CR=0;
A=0;B=0;C=0;D=0;S=0;DR=0;DL=1;
#100;
CR=1;
A=1;B=0;C=1;D=0;
S=2'b10;
end
always #100 S=S+1'b1;
always #25 clk=~clk;
endmodule
这里的时钟可以写
always #25 clk=~clk;
也可以写为
forever
begin
#0;
clk=0;
#25;
clk=~clk
end
所以笔者就用了第一种。嗯,用第一种(因为他又细又短啊[doge])。
仿真效果
分析的话有点复杂……反正实现预期功能就对了……
小结
时序逻辑电路的元件还有组合逻辑电路的元件其实都很简单,按照真值表即使没有对其有深入理解也可以正确地编写出相应的代码。但还是那句话,规范的习惯,深入的理解,这才是我们的真正目的。