前20题大都是组合逻辑电路,时序电路最大的不同就是要用到触发器,程序中一般还是边沿触发,就以第21题为例
第二题来自牛客->verilog快速入门->第21题
1.题目
2.模块函数
代码还是比较简单的,这里只需要注意要用非阻塞赋值即可。
module test2(
input A ,
input clk ,
input rst_n,
output wire Y,
output reg Q1,
output reg Q2
);
always@(posedge clk,negedge rst_n) begin
if(rst_n) begin
Q1 <= ~Q1;
Q2 <= Q2^Q1^A;
end
else begin
Q1<=1'B0;
Q2<=1'B0;
end
end
assign Y = Q1&Q2;
endmodule
3.激励函数
激励文件(顶层文件)代码也需要非阻塞赋值(一开始就是这里搞错了):
module test_top();
reg A;
reg rst_n ;
reg clk = 1;
wire Y,Q1,Q2;
always #5 clk = ~clk;
initial begin
rst_n <= 1'b1;
A <= 1'b1;
#300 $finish;
end
test2 seq(
.A(A),
.rst_n(rst_n),
.clk(clk),
.Y(Y),
.Q1(Q1),
.Q2(Q2)
);
endmodule
4.仿真结果
经过RTL仿真得到上图,但是如果用综合仿真会得到下图情况:
但是行为仿真会得到正常情况:
这里又复习了最开始的学习:
分别是行为仿真、综合仿真、实现仿真,我的理解就是行为仿真相当于代码验证和功能验证,而综合仿真需要根据你事先选择的赛灵思芯片型号来给当前代码用到的逻辑器件配置相应的实际元器件,再进行仿真。实现仿真则是考虑到具体元器件之间的布局布线,会告诉你这些元器件都在哪些位置。
第二题来自牛客->verilog快速入门->第22题
1.题目
2.方法一:触发器
`timescale 1ns/1ns
module seq_circuit(
input C ,
input clk ,
input rst_n,
output wire Y
);
reg Q1,Q0,T;
always@(posedge clk or negedge rst_n ) begin
if(rst_n) begin
Q1 <= Q1&C | Q0&~C;
end
else begin
Q1 <= 1'B0;
end
end
always@(posedge clk or negedge rst_n ) begin
if(rst_n) begin
Q0 <= ~Q1&C | Q0&~C;
end
else begin
Q0 <= 1'B0;
end
end
assign Y = Q1&Q0 | Q1&C;
endmodule
和上一题差不多
3.方法二:状态机
`timescale 1ns/1ns
module seq_circuit(
input C ,
input clk ,
input rst_n,
output wire Y
);
parameter ST0 = 2'b00;
parameter ST1 = 2'b01;
parameter ST2 = 2'b10;
parameter ST3 = 2'b11;
reg[1:0] cur_state;
reg[1:0] next_state;
reg Y_r;
always@(posedge clk or negedge rst_n)
if(!rst_n)
cur_state <= ST0;
else
cur_state <= next_state;
always@(*)
case (cur_state)
ST0: begin
if(C == 1'b0) begin
next_state = ST0;
end else begin
next_state = ST1;
end
end
ST1: begin
if(C == 1'b0) begin
next_state = ST3;
end else begin
next_state = ST1;
end
end
ST2: begin
if(C == 1'b0) begin
next_state = ST0;
end else begin
next_state = ST2;
end
end
ST3: begin
if(C == 1'b0) begin
next_state = ST3;
end else begin
next_state = ST2;
end
end
endcase
always@(*)
case (cur_state)
ST0: begin
Y_r = 1'b0;
end
ST1: begin
Y_r = 1'b0;
end
ST2: begin
if(C == 1'b1)
Y_r = 1'b1;
else
Y_r = 1'b0;
end
ST3: begin
Y_r = 1'b1;
end
endcase
assign Y = Y_r;
endmodule