Verilog小练习- 看时序写代码(09--10)

简介: Verilog小练习- 看时序写代码(09--10)

写在前面


承接本系列上文。整理一些简单的根据时序图编写Verilog代码的实例,帮助新手学习,老手巩固。每次更新两题,根据难度会挑选一些进行讲解。

题目09


image.png

题目09答案


题目和08类似

module test09 (
  input clk,    // Clock
  input en1, // Clock Enable
  input rst_n,  // Asynchronous reset active low
  output reg dout
);
wire add_cnt;
wire end_cnt;
reg  flag;
reg [3:0] cnt ;
assign add_cnt = flag ==1;       
assign end_cnt = add_cnt && cnt== 14-1; 
wire low_flag =  add_cnt && (cnt== 1-1||cnt== 6-1||cnt== 10-1||cnt== 13-1);
always @(posedge clk or negedge rst_n)begin
  if(!rst_n)begin
    cnt <= 0;
  end
  else if(add_cnt)begin
    if(end_cnt)
      cnt <= 0;
    else
      cnt <= cnt + 1;
  end
end
always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
    flag <=0;
  end
  else if(en1==1)begin
    flag <=1;
  end
  else if(end_cnt==1)begin
    flag <=0;
  end
  else begin
    flag <=flag;
  end
end
always  @(posedge clk or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        dout<= 0;
    end
    else if(low_flag==1)begin
        dout<= 0;
    end
    else if(add_cnt==1)begin
      dout<= 1;
    end
    else begin
        dout<= 0;
    end
end
endmodule

测试结果:

image.png

题目10


image.png

题目10答案


最简单的思路通前文的设计方法,对应的计数值设置低输出的flag

版本1


module test10 (
  input clk,    // Clock
  input en1, // Clock Enable
  input rst_n,  // Asynchronous reset active low
  output reg dout
);
wire add_cnt;
wire end_cnt;
reg  flag;
reg [3:0] cnt ;
assign add_cnt = flag ==1;       
assign end_cnt = add_cnt && cnt== 12-1; 
wire low_flag =  add_cnt && (cnt== 1-1||cnt== 3-1
  ||cnt== 4-1||cnt==7-1||cnt== 8-1 ||cnt==9-1);
always @(posedge clk or negedge rst_n)begin
  if(!rst_n)begin
    cnt <= 0;
  end
  else if(add_cnt)begin
    if(end_cnt)
      cnt <= 0;
    else
      cnt <= cnt + 1;
  end
end
always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
    flag <=0;
  end
  else if(en1==1)begin
    flag <=1;
  end
  else if(end_cnt==1)begin
    flag <=0;
  end
  else begin
    flag <=flag;
  end
end
always  @(posedge clk or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        dout<= 0;
    end
    else if(low_flag==1)begin
        dout<= 0;
    end
    else if(add_cnt==1)begin
      dout<= 1;
    end
    else begin
        dout<= 0;
    end
end
endmodule

仿真结果:

image.png

同时我们观察到这里离波形变化呈现规律性,也可以采用计数器进行设计。同样也可以采用状态机。

计数器版本


module test10_1 (
  input clk,    // Clock
  input en1, // Clock Enable
  input rst_n,  // Asynchronous reset active low
  output reg dout
);
reg [5-1: 0] x;
reg [5-1: 0] y;
wire add_cnt;
wire end_cnt;
reg  flag;
reg [3:0] cnt ;
assign add_cnt = flag ==1;       
assign end_cnt = add_cnt && cnt== x+y-1; 
always @(posedge clk or negedge rst_n)begin
  if(!rst_n)begin
    cnt <= 0;
  end
  else if(add_cnt)begin
    if(end_cnt)
      cnt <= 0;
    else
      cnt <= cnt + 1;
  end
end
wire add_cnt1;
wire end_cnt1;
reg [3:0] cnt1 ;
assign add_cnt1 = end_cnt;       
assign end_cnt1 = add_cnt1 && cnt1== 3-1; 
wire high_flag =  add_cnt && cnt== x-1;
always @(posedge clk or negedge rst_n)begin
  if(!rst_n)begin
    cnt1 <= 0;
  end
  else if(add_cnt1)begin
    if(end_cnt1)
      cnt1 <= 0;
    else
      cnt1 <= cnt1 + 1;
  end
end
always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
    flag <=0;
  end
  else if(en1==1)begin
    flag <=1;
  end
  else if(end_cnt1==1)begin
    flag <=0;
  end
  else begin
    flag <=flag;
  end
end
always  @(*)begin
    if(cnt1==0)begin
    x<=1;
    y<=1;
  end
  else if(cnt1==1)begin
    x<=2;
    y<=2;
  end
  else begin
    x<=3;
    y<=3;
  end
end
reg  dout_r;
always  @(posedge clk or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        dout_r<= 0;
    end
    else if(high_flag==1)begin
        dout_r<= 1;
    end
    else if(end_cnt==1)begin
      dout_r<= 0;
    end
end
always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
    dout<=0;
  end
  else begin
    dout<=dout_r;
  end
end
endmodule

image.png

状态机版本


module test10_2 (
  input clk,    // Clock
  input en1, // Clock Enable
  input rst_n,  // Asynchronous reset active low
  output reg dout
);
reg [4-1: 0] x;
wire add_cnt;
wire end_cnt;
reg [3:0] cnt ;
reg  flag;
assign add_cnt = flag==1;       
assign end_cnt = add_cnt && cnt==2*x-1; 
always @(posedge clk or negedge rst_n)begin
  if(!rst_n)begin
    cnt <= 0;
  end
  else if(add_cnt)begin
    if(end_cnt)
      cnt <= 0;
    else
      cnt <= cnt + 1;
  end
end
//-----------------状态机-------------------
//--------------<状态机参数>----------------
parameter       S0 =4'b0000,
        S1 =4'b0001,
        S2 =4'b0010,
        S3 =4'b0100;
//---------------<信号定义>------------------
reg [4- 1 : 0] state_c, state_n;
//设计转移条件
wire S0toS1_condition  = state_c==  S0  && end_cnt==1;
wire S1toS2_condition  = state_c==  S1  && end_cnt==1;
wire S2toS3_condition  = state_c==  S2  && end_cnt==1;
//描述次态寄存器迁移到现态寄存器
always@(posedge clk or negedge rst_n)begin
  if(!rst_n)begin
    state_c <= S0;
  end
  else begin
    state_c <= state_n;
  end
end
//描述状态转移条件判断
always@(*)begin
  case(state_c)
    S0:begin
      if(S0toS1_condition)begin
        state_n = S1;
      end
      else begin
        state_n = state_c;
      end
    end
    S1:begin
      if(S1toS2_condition)begin
        state_n = S2;
      end
      else begin
        state_n = state_c;
      end
    end
    S2:begin
      if(S2toS3_condition)begin
        state_n = S3;
      end
      else begin
        state_n = state_c;
      end
    end
    S3:begin
      state_n = state_c;
    end
    default:begin
      state_n = S0;
    end
  endcase
end
//输出
always @(*)begin
  if(rst_n==0)begin
    x<=0;
  end
  else if(state_c==S0)begin
    x<=1;
  end
  else if(state_c==S1)begin
    x<=2;
  end
  else if(state_c==S2)begin
    x<=3;
  end
end
always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
    flag <=0;
  end
  else if(en1==1)begin
    flag <=1;
  end
  else if(state_c==S3)begin
    flag <=0;
  end
  else begin
    flag <=flag;
  end
end
reg  doutr;
always @(posedge clk or negedge rst_n)begin
  if(rst_n==0)begin
    doutr<=0;
  end
  else if(state_c==S3)begin
    doutr<=0;
  end
  else if(end_cnt==1)begin
    doutr<=0;
  end
  else if(cnt==x-1 && flag==1)begin
    doutr<=1;
  end
end
always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
    dout<=0;
  end
  else begin
    dout<=doutr;
  end
end
endmodule

仿真结果

image.png

目录
相关文章
|
存储 数据采集
时序逻辑电路的应用及其作用
一、什么时序逻辑电路 时序逻辑电路是一种电子电路,用于处理和存储时序信息。它通过使用时钟信号来控制电路的行为,以实现特定的功能。 时序逻辑电路通常由触发器和组合逻辑电路组成。触发器是一种存储器件,可以存储和传递电信号。组合逻辑电路则根据输入信号的组合产生输出信号。 时序逻辑电路的行为是根据时钟信号的变化来确定的。时钟信号是一个周期性的信号,用于同步电路的操作。在每个时钟周期中,电路根据输入信号和当前状态来计算输出信号,并在时钟信号的上升沿或下降沿时更新状态。 时序逻辑电路可以用于实现各种功能,如计数器、状态机、时序控制器等。它在数字系统中起着重要的作用,用于处理时序信息和控制电路的行为。 二、
757 0
|
6月前
|
存储 异构计算
FPGA入门(4):时序逻辑(一)
FPGA入门(4):时序逻辑
64 0
|
8月前
|
算法 异构计算
m基于FPGA的Alamouti编码verilog实现,包含testbench测试文件
m基于FPGA的Alamouti编码verilog实现,包含testbench测试文件
86 5
|
芯片 异构计算
第三章 硬件描述语言verilog(三)功能描述-时序逻辑
第三章 硬件描述语言verilog(三)功能描述-时序逻辑
280 0
第三章 硬件描述语言verilog(三)功能描述-时序逻辑
|
存储 算法 异构计算
m基于FPGA的数据串并并串转换系统verilog实现,包含testbench,可以配置并行数量
m基于FPGA的数据串并并串转换系统verilog实现,包含testbench,可以配置并行数量
390 0
|
算法 异构计算
基于FPGA的直接序列扩频通信verilog设计,包括汉明编译码,扩频解扩,同步模块以及testbench
基于FPGA的直接序列扩频通信verilog设计,包括汉明编译码,扩频解扩,同步模块以及testbench
322 0
基于FPGA的直接序列扩频通信verilog设计,包括汉明编译码,扩频解扩,同步模块以及testbench
|
编译器 芯片 异构计算
【数字逻辑 | 组合电路基础】Verilog语法
【数字逻辑 | 组合电路基础】Verilog语法
【数字逻辑 | 组合电路基础】Verilog语法
Verilog 时序控制
Verilog 提供了 2 大类时序控制方法:时延控制和事件控制。事件控制主要分为边沿触发事件控制与电平敏感事件控制。
159 0
|
异构计算
FPGA(4)--VHDL--4位D触发器
FPGA(4)--VHDL--4位D触发器
361 0
FPGA(4)--VHDL--4位D触发器
Verilog语法入门(二)多bit逻辑门
Verilog HDL是一种硬件描述语言(HDL:Hardware Description Language),以文本形式来描述数字系统硬件的结构和行为的语言,用它可以表示逻辑电路图、逻辑表达式,还可以表示数字逻辑系统所完成的逻辑功能。 Verilog HDL和VHDL是世界上最流行的两种硬件描述语言,都是在20世纪80年代中期开发出来的。前者由Gateway Design Automation公司(该公司于1989年被Cadence公司收购)开发。两种HDL均为IEEE标准。
219 0