〇、关于本文
本文我的Verilog课程作业,由于我尚处在初学阶段,并且这门课和我实际工作的关系并不大,因此代码仅供参考。
我使用的编译环境为iverilog,在Windows下运行。
一、题目及代码
设计一个101序列发生器(a.v内容),同步时钟触发。设计一个序列检测器(b.v内容),并与上面的发生器连接,形成一个完整测试系统(c.v内容)。
文件a.v代码
module seq_101(clk_out, clr, clk);
input clk;
input clr;
output clk_out;
reg clk_out;
integer counter = 0;
always @(negedge clr or posedge clk)
begin
if(!clr)
begin
clk_out = 3'bxxx;
counter = 0;
end
else
begin
counter = counter + 1;
if(counter == 1)
begin
clk_out = 1;
end
else if(counter == 2)
begin
clk_out = 0;
counter = 0;
end
end
end
endmodule
文件b.v代码
module seq_check_101(out, clr, clk, din);
input din;
input clr;
input clk;
output out;
reg out;
reg [2:0] state, nextstate;
parameter Idle = 2'b00;
parameter First = 2'b01;
parameter Second = 2'b10;
initial
begin
state = Idle;
end
always @(negedge clr or posedge clk)
begin
if(!clr)
state <= Idle;
else
state <= nextstate;
end
always @(negedge clr or posedge clk)
begin
case(state)
Idle:
if(din)
nextstate <= First;
else
nextstate <= Idle;
First:
if(din)
nextstate <= First;
else
nextstate <= Second;
Second:
if(din)
nextstate <= Idle;
else
nextstate <= Idle;
default:
nextstate <= Idle;
endcase
end
always @(state)
begin
if(state == Idle)
out <= 0;
else if(state == First)
out <= 1;
else
out <= 2;
/*
if(!clr)
out <= 0;
else
if(state == Second)
out <= 1;
else
out <= 0;
*/
end
endmodule
文件c.v代码
module test();
reg clk;
reg clr;
wire clk_out;
wire out;
seq_101 dut1(.clk_out(clk_out), .clr(clr), .clk(clk));
seq_check_101 dut2(.out(out), .clr(clr), .clk(clk), .din(clk_out));
initial begin
clk = 0; clr = 0;
#5 clr = 1;
end
always #5 clk = ~clk;
initial begin
$dumpfile("./test.vcd");
$dumpvars(-1, test);
$dumpon();
#200
$dumpoff();
$finish;
end
always @(posedge clk)
$display("%t: clk_out:%b\tclk:%b\tout:%b", $time, clk_out, clk, out);
endmodule
运行结果
gtkwave.exe中显示的波形
END