分析:T触发器的特点,输入T为1时,输出翻转;输入T为0时,输出保持,另外还要注意是异步复位。两个这种触发器串联起来,第一个的输出作为第二个的输入。
解法一:使用异或运算,相同为0,不同为1
- `timescale 1ns/1ns
- module Tff_2 (
- input wire data, clk, rst,
- output reg q
- );
- //*************code***********//
- reg data_1;
- always@(posedge clk or negedge rst)
- begin
- if(rst == 1'b0)
- data_1 <= 1'b0;
- else
- data_1 <= data ^ data_1;
- end
- always@(posedge clk or negedge rst)
- begin
- if(rst == 1'b0)
- q <= 1'b0;
- else
- q <= data_1 ^ q;
- end
-
- //*************code***********//
- endmodule
解法二:
- `timescale 1ns/1ns
- module Tff_2 (
- input wire data, clk, rst,
- output reg q
- );
- //*************code***********//
- reg data_1;
- always@(posedge clk or negedge rst)begin
- if(!rst)begin
- data_1 <= 1'b0;
- q <= 1'b0;
- end
- else begin
- data_1 <= data ^ data_1;
- q <= data_1 ^ q;
- end
- end
- //*************code***********//
- endmodule
解法三:此方法使用了三态运算符
- `timescale 1ns/1ns
- module Tff_2 (
- input wire data, clk, rst,
- output reg q
- );
- reg reg1;
- always @(posedge clk or negedge rst) begin
- if(!rst) begin
- reg1 <= 0 ;
- q <= 0 ;
- end
- else begin
- reg1 <=data? ~reg1 : reg1 ;
- q <=reg1? ~q : q ;
- end
-
- end
-
- endmodule
解法四:
- `timescale 1ns/1ns
- module Tff_2
- (
- input wire clk,rst,data,
- output reg q
- );
- reg data1;
- always@(posedge clk or negedge rst)
- begin
- if(!rst)
- data1 <= 1'b0;
- else if(data == 1'b1)
- data1 <= ~data1;
- else
- data1 <= data1;
- end
- always@(posedge clk or negedge rst)
- begin
- if(!rst)
- q <= 1'b0;
- else if(data1 == 1'b1)
- q <= ~q;
- else
- q <= q;
- end
- endmodule
Testbench
- `timescale 1ns/1ns
- module testbench();
- reg clk=0;
- reg rst=0;
- //always #5 clk = ~clk; // Create clock with period=10
- reg data;
- wire q;
- // A testbench
- initial
- begin
- $dumpfile("out.vcd");
- $dumpvars(0, testbench);
- repeat(20)
- #2 clk = ~clk;
- end
-
- Tff_2 Tff_2_inst
- (
- .clk (clk),
- .rst (rst),
- .data (data),
- .q (q)
- );
- initial
- begin
- data = 0;
- #6
- rst = 1;
- data = 0;
- #6
- data =1;
- rst =1;
- #6
- data = 0;
- rst =1;
- #6
- data = 1;
- rst = 1;
- end
-
- endmodule
注意:如果报错
- cannot be driven by primitives or continuous assignment
- Output port expression must support continuous assignment.
那是因为reg不应连接到模块输出,改成wire就好
verilog中repeat的用法和例子
repeat循环语句执行指定循环次数,如果循环计数表达式的值不确定时,即为 x 或z 时,那么循环次数按 0 处理。repeat的语法是:
repeat(循环次数表达式)begin
语句块;
end
其中, “循环次数表达式”用于指定循环次数,可以是一个整数、变量或者数值表达式。
如果是变量或者数值表达式,其数值只在第一次循环时得到计算,从而得以事先确定循环次
数; “语句块”为重复执行的循环体。
在可综合设计中, “循环次数表达式”必须在程序编译过程中保持不变。