verilog当case语句功能需要不同时序时如何选择

2 篇文章 0 订阅
1 篇文章 0 订阅

     最近又遇到新的问题,当我在case语句的使用时候所需时钟分别为5MHZ(代码内为clk)和2MHZ(代码内为clkl),但该情况无法在case语句中单独实现。于是我就想到可以在需要另一个时钟的时候跳出case语句,用两个always进行衔接。

例如:在大时钟clkl中,case语句进行0、1后在小时钟clk之中进行所需运算,再回到大时钟内进行case 2。

这个方法可以很好的解决的问题是:用大时钟核对数据地址等,用小时钟来抓取所需要的数据。

(逻辑上我自己称之为跳出时钟的选择语句)

代码测试如下:

1.test源码

module test(
input clkl,//5MHZ
input clk,//2MHZ
input rstn,//复位信号
output reg [2:0]cnt,
output reg [2:0]cnt1,
output reg [2:0]cnt2,
output reg [2:0]cnt3,
output reg [2:0] a,//用于case的选择
output reg h、、用于两个always的衔接
);
always@(*)begin//复位信号
 if(rstn)begin
    cnt <= 0;
    cnt1 <= 0;
    cnt2 <= 0;
    cnt3 <= 0;
    a <= 0;
 end
end
always@(posedge clkl)begin
  case (a)
   0:begin//进行case0
         if (cnt == 3'd5)begin
            cnt <= 0;
            a<= 1;
         end else begin
             cnt <= cnt+1;
         end
       end
    1:begin//进行case1,当cnt1等于5时候,跳出case进入下一个always用于抓取信号
         if (cnt1 == 3'd5)begin
            h <= 1;
            cnt1 <= cnt1;
         end else begin
             cnt1 <= cnt1+1;
         end
       end
    2:begin 
         if (cnt2 === 3'd6)begin//当下一个always模块进行完毕后回到case2
            cnt2 <= cnt2;
            a<=0;
            h<=0;
         end else begin
             cnt2 <= cnt2+1;
         end
       end
     endcase
end
always@(posedge clk)begin//当这个信号抓取完毕后回到case2继续进行循环
    if(h==1)begin
       if(cnt3== 3'd4)begin
          a <= 2;
          cnt3 <= cnt3;
       end else begin
          cnt3 <= cnt3 + 1;
       end
    end
end
endmodule

2.分频器(用的是奇数分频器)

module clk_gen (
    input wire clk,      // 5MHz 输入时钟信号
    output reg clkl      // 2MHz 输出时钟信号
);

reg [2:0] count;

always @(clk)    // 在输入时钟的上升沿触发
begin
    count <= count + 1;      // 计数器递增
    if (count == 3'd2)     // 当计数器达到约一半时
    begin
        clkl <= ~clkl;         // 重置计数器
    end else if (count ==3'd4)
    begin
        clkl <= ~clkl;
        count <= 0;
end
end
endmodule

3例化

`include "clk_gen.v"//因为用的是vcs进行仿真,所以要加上,如果用的是其他软件大家自行更改
`include "test.v"
module stest(
input clk,rstn,
output clkl,
output [2:0]cnt,
output [2:0]cnt1,
output [2:0]cnt2,
output [2:0]cnt3,
output [2:0] a,
output h
);
clk_gen t_clk_gen(
                  .clk(clk),
		  .clkl(clkl)
		);
test t_test(
            .rstn(rstn),
            .clk(clk),
            .clkl(clkl),
            .cnt(cnt),
            .cnt1(cnt1),
            .cnt2(cnt2),
            .cnt3(cnt3),   
            .a(a),
            .h(h) 
            );
endmodule

4.顶层文件

`timescale 1ns/1ns
`define PERIOD 100
`include "stest.v"
module top;
      reg clk,rstn;
      wire clkl;
      wire [2:0]cnt;
      wire [2:0]cnt1;
      wire [2:0]cnt2;
      wire [2:0]cnt3;
      wire [2:0]a;
      wire h;
stest t_stest(
            .rstn(rstn),
            .clk(clk),
            .clkl(clkl),
            .cnt(cnt),
            .cnt1(cnt1),
            .cnt2(cnt2),
            .cnt3(cnt3),   
            .a(a),
            .h(h) 
      );
initial begin
        clk = 0;
        rstn = 0;
end 
always #100 clk = ~clk;
initial begin
       #100 rstn <= 1;
       #100 rstn <= 0;
end
endmodule

5.VCS仿真结果

结果仿真正确,是我们想要的结果

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值