2022/12/3 14:41
以下内容源自Verilog
仅供学习交流使用
Verilog
2段式
3段式
Mealy状态机和Moore状态机
module seadeta_moore (input wire clk,input wire clr,input wire din,output reg dout);reg [2:0] present_state, next_state;parameter s0=3'b000,s1=3 'b001,s2=3 'b010,s3=3'b011,s4=3'b100;
endmodule
always @(posedge clk or posedge clr)beginif(clr==1) present_state<=s0;else present_state<=next_state;end
always @(*)begincase (present_state)s0: if (din==1)next_state=s1;else next_state=s0;s1: if(din==1) next_state=s2;else next_state=s0;s2: if (din==0) next_state=s3;else next_state=s2;s3: if(din==1) next_state =s4;else next_state= s0;s4: if(din==0) next_state = s0;else next_state= s2;default next_state= s0;endcaseend
always@(*)beginif(present_state==s4) dout=1;else dout =0;end
//moore型
//考虑重复序列
module seadeta_moore (input wire clk,input wire clr,input wire din,output reg dout);//代码设计--端口信号声明reg [2:0] present_state, next_state;parameter s0=3'b000,s1=3'b001,s2=3'b010,s3=3'b011,s4=3'b100;//状态寄存器//确定初始状态//每一个clk的上升沿,修改状态寄存器的值always @(posedge clk or posedge clr)beginif(clr==1) present_state<=s0;else present_state<=next_state;end//次态生成逻辑设计(C1模块)//根据输入和当前状态,决定转移的下一个状态always @(*)begincase (present_state)s0: if (din==1)next_state=s1;else next_state=s0;s1: if(din==1) next_state=s2;else next_state=s0;s2: if (din==0) next_state=s3;else next_state=s2;s3: if(din==1) next_state =s4;else next_state= s0;s4: if(din==0) next_state = s0;else next_state= s2;default next_state= s0;endcaseend//输出逻辑设计(C2模块)//根据当前的状态决定当前的输出always@(*)beginif(present_state==s4) dout=1;else dout =0;end
endmodule
测试
module seadeta_tb;reg clk;reg clr;reg din;wire dout;seadeta_moore m1(clk,clr,din,dout);always#5 clk=~clk;initialbeginclk=0;clr=1;#10 clr=0;din=0;#10 din=1;#10 din=1;#10 din=0;#10 din=1;#10 din=1;#10 din=0;#10 din=1;#10 din=0;#10 din=1;#10 din=1;#10 din=0;#10 din=1;endendmodule
结果
序列检测器就是将一个指定的序列从数字码流中检测出来。
当输入端出现序列1101时,输出为1,否则输出为0。在此不考虑重复序列,即出现指定序列后就重新开始序列检测,不再考虑以前的数据。
//mealy型
//不考虑重复序列
module seadeta_mealy(input wire clk,input wire clr,input wire din,output reg dout);reg [2:0] present_state, next_state;parameter s0=3'b000,s1=3'b001,s2=3'b010,s3=3'b011;//时序逻辑always @(posedge clk or posedge clr)beginif(clr==1) present_state<=s0;else present_state<=next_state;end//组合逻辑always @(*)begincase (present_state)s0: if (din==1)begin next_state=s1; dout=0; endelse begin next_state=s0; dout=0; ends1: if(din==1) begin next_state=s2; dout=0; endelse begin next_state=s0; dout=0; ends2: if (din==0) begin next_state=s3; dout=0; endelse begin next_state=s2; dout=0; ends3: if(din==1) begin next_state =s0; dout=1; endelse begin next_state= s0; dout=0; enddefault begin next_state= s0; dout=0; endendcaseendendmodule
测试
module seadeta_tb;reg clk;reg clr;reg din;wire dout;//seadeta_moore m1(clk,clr,din,dout);seadeta_mealy m2(clk,clr,din,dout);always#5 clk=~clk;initialbeginclk=0;clr=1;#10 clr=0;din=0;#10 din=1;#10 din=1;#10 din=0;#10 din=1;#10 din=1;#10 din=0;#10 din=1;#10 din=0;#10 din=1;#10 din=1;#10 din=0;#10 din=1;endendmodule
结果
module traffic(input wire clk,input wire clr,output reg [5:0]lights);reg [2:0]state;reg [3:0]count;parameter s0=3'b000,s1=3'b001,s2=3'b010,s3=3'b011,s4=3'b100,s5=3'b101;parameter sec5=5,sec1=1;
endmodule
always @(posedge clk or posedge clr)beginif(clr==1)beginstate<=s0;count<=0;endelsecase (state)s0: if(count
always @(*)begincase (state)s0: lights=6'b100001;s1: lights=6'b100010;s2: lights=6'b100100;s3: lights=6'b001100;s4: lights=6'b010100;s5: lights=6'b100100;default lights=6'b100001;endcaseend
module traffic(input wire clk,input wire clr,output reg [5:0]lights);//程序设计-----输入输出信号声明reg [2:0]state;reg [3:0]count;//此位宽由sec5,sec1决定parameter s0=3'b000,s1=3'b001,s2=3'b010,s3=3'b011,s4=3'b100,s5=3'b101;parameter sec5=5,sec1=1;//此单位为时钟周期//状态寄存器和状态转移逻辑设计always @(posedge clk or posedge clr)beginif(clr==1)beginstate<=s0;count<=0;endelsecase(state)s0: if(count
测试
module traffic_tb;reg clk;reg clr;wire [5:0]lights;traffic u1(clk,clr,lights);always #5 clk=~clk;initialbeginclk=0;clr=1;#10clr=0;endendmodule
结果
2022/12/3 16:21
这篇博客能写好的原因是:站在巨人的肩膀上
这篇博客要写好的目的是:做别人的肩膀
开源:为爱发电
学习:为我而行