在 Vivado 仿真中立即分配非阻塞赋值

如何解决在 Vivado 仿真中立即分配非阻塞赋值

在实现cordic 算法时,我的非阻塞赋值立即分配变量,而不是在一个时钟周期后。我不知道为什么。我的代码或 Vivado 设计套件有问题吗? 在我的代码中,我需要用 z[0] 分配 z[0] <= angle。但是,在我的 Vivado 模拟器中,z[0] 只是与 angle 同时变化。

环境:Windows10,Vivado 2020.2的默认模拟器

`timescale 1ns/10ps

module cordic_tb #(

)(

);
    localparam real PI = 3.1415926535;
    logic clk,rst_n,en;
    
    logic signed [31:0] step=integer'((3/180.0)*(2.0**31.0));
    logic signed [31:0] angle;
    logic signed [31:0] cosine,sine;
    initial begin
        clk=0;
        en=1;
        forever #50 clk=~clk;
    end
    initial begin
        rst_n=0;
        #100 rst_n=1;
    end
    always_ff @( posedge clk ) begin
        if(!rst_n) angle='0;
        else if(en) angle=angle+step;
    end
    cordic #()
    theCordicInst(clk,en,angle,cosine,sine);
    //test 45°
    /*
    initial begin
        clk=0;
        rst_n=1;
        en=1;
        repeat(62)
        begin
            #5 clk = ~clk;
            if(cosine || sine)
            begin
                $display((real'(cosine))*(2.0**(-31.0)));
                $display((real'(sine))*(2.0**(-31.0)));
                $display($sin((45.0/180.0)*3.1415926535)); 
            end
        end
    end
    Cordic #()
    theCordicInst(clk,32'h20000000,sine);
    */
endmodule

module cordic #(
    parameter integer DW = 32,parameter real K = 0.6
)(
    input wire clk,input wire signed [DW-1:0] angle,output logic signed [DW-1:0] cosine,sine
);
    wire signed [DW-1:0] atan_table[0:29];
    logic signed [DW-1:0] x_start,y_start;
    logic signed [DW-1:0] x[0:30],y[0:30],z[0:30];
    wire [1:0] domain;

    assign atan_table[00]=32'b00100000000000000000000000000000;
    assign atan_table[01]=32'b00010010111001000000010100011101;
    assign atan_table[02]=32'b00001001111110110011100001011011;
    assign atan_table[03]=32'b00000101000100010001000111010100;
    assign atan_table[04]=32'b00000010100010110000110101000011;
    assign atan_table[05]=32'b00000001010001011101011111100001;
    assign atan_table[06]=32'b00000000101000101111011000011110;
    assign atan_table[07]=32'b00000000010100010111110001010101;
    assign atan_table[08]=32'b00000000001010001011111001010011;
    assign atan_table[09]=32'b00000000000101000101111100101110;
    assign atan_table[10]=32'b00000000000010100010111110011000;
    assign atan_table[11]=32'b00000000000001010001011111001100;
    assign atan_table[12]=32'b00000000000000101000101111100110;
    assign atan_table[13]=32'b00000000000000010100010111110011;
    assign atan_table[14]=32'b00000000000000001010001011111001;
    assign atan_table[15]=32'b00000000000000000101000101111100;
    assign atan_table[16]=32'b00000000000000000010100010111110;
    assign atan_table[17]=32'b00000000000000000001010001011111;
    assign atan_table[18]=32'b00000000000000000000101000101111;
    assign atan_table[19]=32'b00000000000000000000010100010111;
    assign atan_table[20]=32'b00000000000000000000001010001011;
    assign atan_table[21]=32'b00000000000000000000000101000101;
    assign atan_table[22]=32'b00000000000000000000000010100010;
    assign atan_table[23]=32'b00000000000000000000000001010001;
    assign atan_table[24]=32'b00000000000000000000000000101000;
    assign atan_table[25]=32'b00000000000000000000000000010100;
    assign atan_table[26]=32'b00000000000000000000000000001010;
    assign atan_table[27]=32'b00000000000000000000000000000101;
    assign atan_table[28]=32'b00000000000000000000000000000010;
    assign atan_table[29]=32'b00000000000000000000000000000001;

    assign x_start= integer'(K*(2.0**(DW-1.0)));
    assign y_start='0;
    assign domain=angle[31:30];

    // convert angle to -pi/2 ~ pi/2,xy start point changes too
    always_ff @( posedge clk ) begin
        if(~rst_n)
        begin
            x[0] <= '0;
            y[0] <= '0;
            z[0] <= '0;
        end
        else if(en)
        begin
            case(domain)
                2'b00,2'b11:
                begin
                    x[0] <=  x_start;
                    y[0] <=  y_start;
                    z[0] <= angle;
                end
                2'b01:
                begin
                    x[0] <= -y_start;
                    y[0] <=  x_start;
                    z[0] <= {2'b00,angle[29:0]};
                end
                2'b10:
                begin
                    x[0] <=  y_start;
                    y[0] <= -x_start;
                    z[0] <= {2'b11,angle[29:0]};
                end
            endcase
        end
    end
    generate
        for(genvar i=0;i<30;i=i+1)
        begin:xyz
            wire s=z[i][31];
            wire signed [DW-1:0] x_shr=x[i]>>>i;
            wire signed [DW-1:0] y_shr=y[i]>>>i;

            always_ff @( posedge clk ) begin
                if(~rst_n)
                begin
                    x[i+1] <= '0;
                    y[i+1] <= '0;
                    z[i+1] <= '0;
                end
                else if(en)
                begin
                    x[i+1] <= s ? x[i]+y_shr : x[i]-y_shr;
                    y[i+1] <= s ? y[i]-x_shr : y[i]+x_shr;
                    z[i+1] <= s ? z[i]+atan_table[i] : z[i]-atan_table[i];
                end
            end
        end
    endgenerate
    assign cosine=x[30];
    assign sine  =y[30];
endmodule

enter image description here

解决方法

问题出在测试平台代码中。在测试平台中也使用非阻塞赋值。更改:

always_ff @( posedge clk ) begin
    if(!rst_n) angle='0;
    else if(en) angle=angle+step;
end

到:

always_ff @( posedge clk ) begin
    if (!rst_n)  angle <= '0;
    else if (en) angle <= angle+step;
end

现在,z[0]angle 后更改一个时钟:

enter image description here

, verilog 仿真中的

非阻塞分配总是在当前时钟周期内分配数据。唯一的区别是它在所有阻塞分配完成后分配数据。

就您而言,您有两个陈述:

always_ff @( posedge clk ) begin
     angle=angle+step;
end

always_ff @( posedge clk ) begin
     z[0] <= angle;

在 'posedge clk' 中,你会发生两个事件:

  1. 阻止分配立即更新角度
  2. 非阻塞分配计划更新到 z[0] 并使用上面更新的 angle 值。
  3. z[0] 赋值。

verilog 保证首先发生“阻塞”。因此,您的 z[0] 将跟随 angle

如果您将第一个分配更改为非阻塞

always_ff @( posedge clk ) begin
     angle<=angle+step;
end

将发生以下情况:

  1. 非阻塞分配计划在所有阻塞分配后更新为angle。它的值不会立即改变。
  2. 非阻塞分配计划更新为z[0],但它将使用尚未更新的angle值。
  3. 使用 anglez[0]值更新它们在阻塞赋值区域中的值。

现在,z[0] 包含 angle 的旧值,angle 更新为新值。这模拟了链式触发器的行为,这就是在所有状态设备中使用 nbas 的原因。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res