由于本电路极其简单,原理不做解释
JK触发器
真值表
硬件描述语言
代码
//边沿JK触发器-时序逻辑
//作者:刘航宇 2023/4/15
//Email:hyliu@ee.ac.cn
module jk_trigger(clk,j,k,q,qb);
input clk,j,k;
output q,qb;
reg q;
wire qb;
always @(posedge clk) begin
case ({j,k})
2'b00: q<=1; //jk=00,保持
2'b01: q<=1'b0; //jk=01,则触发器置0
2'b10: q<=1'b1; //jk=10,则触发器置1
2'b11: q<=~q; //11,翻转
//组合逻辑中,为避免生成锁存器,好的代码风格是if语句都加上else,case语句都加上default。
//时序逻辑中,“若无必要,尽量不加else和default”——以减小数据翻转机会,低功耗。
//故此处不写default
endcase
end
assign qb = ~q;
endmodule
测试文件
//jk触发器测试文件
`timescale 1ns/1ps
module jk_trigger_tb;
reg j,k,clk;//输入reg是因为要initial
wire q,qb;
always begin
#5 clk = ~clk;
end
//初始化
//下面这个产生fsdb是Synopsys VCS&Makefile脚本会用到,如果你用Medelsim仿真请删掉这个initial语句以免报错
initial begin
$fsdbDumpfile("tb.fsdb");//这个是产生名为tb.fsdb的文件
$fsdbDumpvars;
end
initial begin
clk = 0;
j = 1'b0;
k = 1'b0;//保持
#30 begin j=1'b0;k=1'b1; end //置0
#20 begin j=1'b1;k=1'b0; end //置1
#20 begin j=1'b0;k=1'b0; end //保持
#20 begin j=1'b1;k=1'b1; end //翻转
#200 $finish;
end
jk_trigger u1(.j(j),.k(k),.clk(clk),.q(q),.qb(qb));
endmodule
JK触发器时序
上升沿触发,可以看到时序完全正确
JK触发器电路图
之所以这样综合电路综合出一个D触发器,是考虑标准单元库的面积与时序的折中,标准单元相当于基本晶体管搭建而成,比如反相器占用2个晶体管,与非门占用4个晶体管,具体不在赘叙。
JK触发器性能--SMIC180nm工艺
RS触发器
真值表
RS硬件描述语言
代码
//边沿JK触发器-时序逻辑
//作者:刘航宇 2023/4/15
//Email:hyliu@ee.ac.cn
module rs_trigger(
input wire clk,r,s,
output reg q,
output wire qb
);
always @(posedge clk) begin
case ({r,s})
2'b00: q<=q; //r,s同时为低电平,触发器保持状态不变
2'b01: q<=1'b1; //触发器置1
2'b10: q<=1'b0; //触发器置0
2'b11: q<=1'bx; //不定态
endcase
end
assign qb = ~q;
endmodule
测试代码
`timescale 1ns/1ps
module rs_trigger_tb();
reg clk,r,s;
wire q,qb;
always begin
#5 clk = ~clk;
end
//初始化
initial begin
clk = 0;
r = 1'b0;
s = 1'b0;//保持
#30 r=1'b0;s=1'b1; //置1
#20 r=1'b1;s=1'b0; //置0
#20 r=1'b0;s=1'b0; //保持
#20 r=1'b1;s=1'b1; //禁止
#200 $stop;
end
rs_trigger u2(.clk(clk),.r(r),.s(s),.q(q),.qb(qb));
endmodule
RS触发器时序
上升沿触发,可以看到时序完全正确
评论 (0)