这是一个给学生朋友写的Verilog 101序列检测的示例程序。
The following is the state machine diagram by the fizzim.
perl fizzim.pl seq101.fzm > seq101.v
RTL are generated like this:
// Created by fizzim.pl version 5.20 on 2019:04:26 at 14:00:34 (www.fizzim.com)
module seq101 (
output wire det,
input wire clk,
input wire rstn,
input wire sin
);
// state bits
parameter
state0 = 3'b000, // extra=00 det=0
state1 = 3'b010, // extra=01 det=0
state2 = 3'b100, // extra=10 det=0
state3 = 3'b001; // extra=00 det=1
reg [2:0] state;
reg [2:0] nextstate;
// comb always block
always @* begin
nextstate = state; // default to hold value because implied_loopback is set
case (state)
state0: begin
if (sin == 1) begin
nextstate = state1;
end
else begin
nextstate = state0;
end
end
state1: begin
if (sin == 0) begin
nextstate = state2;
end
else begin
nextstate = state1;
end
end
state2: begin
if (sin == 1) begin
nextstate = state3;
end
else begin
nextstate = state0;
end
end
state3: begin
if (sin == 0) begin
nextstate = state2;
end
else begin
nextstate = state1;
end
end
endcase
end
// Assign reg'd outputs to state bits
assign det = state[0];
// sequential always block
always @(posedge clk or negedge rstn) begin
if (!rstn)
state <= state0;
else
state <= nextstate;
end
// This code allows you to see state names in simulation
`ifndef SYNTHESIS
reg [47:0] statename;
always @* begin
case (state)
state0:
statename = "state0";
state1:
statename = "state1";
state2:
statename = "state2";
state3:
statename = "state3";
default:
statename = "XXXXXX";
endcase
end
`endif
endmodule
`timescale 1ns/1ps
module tb();
reg clk,
rstn,
sin;
wire det;
initial begin
clk = 0;
forever #10 clk = ~clk;
end
initial begin
rstn = 1'b0;
#22 rstn = 1'b1;
end
initial begin
repeat(100)begin
@(negedge clk)
sin = {$random};
end
$finish;
end
initial begin
$dumpfile("seq101_tb.vcd");
$dumpvars();
end
seq101 u_seq101
(/*AUTOINST*/
// Outputs
.det (det),
// Inputs
.clk (clk),
.rstn (rstn),
.sin (sin));
endmodule // tb
iverilog tb.v seq101.v
./a.out
gtkwave seq101_tb.vcd
The following picture shows the simulation result.
In the waveform, we have detected all the '101' sequences, and '10101' are detected twice. It matches the goal.
.PHONY: all rtl sim wave
all:
@echo "make all: help informataion"
@echo "make rtl: generate rtl by fizzim"
@echo "make sim: run simulation"
@echo "make wave: open waveform"
rtl:
perl fizzim.pl seq101.fzm > seq101.v
sim:
iverilog tb.v seq101.v
./a.out
wave:
gtkwave seq101_tb.vcd