Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Verilog中的算术方程除以带时钟的电平,接收“;闩锁警告“;请提供建议_Verilog_Fpga_Fsm_Integer Arithmetic - Fatal编程技术网

Verilog中的算术方程除以带时钟的电平,接收“;闩锁警告“;请提供建议

Verilog中的算术方程除以带时钟的电平,接收“;闩锁警告“;请提供建议,verilog,fpga,fsm,integer-arithmetic,Verilog,Fpga,Fsm,Integer Arithmetic,更新:我正在编辑这个问题,以将方程更改为更简单的方程,尽管问题大致相同,但这次我实际上可以让它给出正确的计算答案,但我一直存在“锁存”问题。(我原来的方程也运行良好,但相同的警告锁存问题) 我想一步一步地做一个简单的等式,如下所示: c = 50 / (|a - 2|^2 + |b - 5|^2) 数据是无符号的二进制32位值,减法结果也是无符号的(绝对值),我要做的是使用时钟分几步执行 |a - 2| ,

更新:我正在编辑这个问题,以将方程更改为更简单的方程,尽管问题大致相同,但这次我实际上可以让它给出正确的计算答案,但我一直存在“锁存”问题。(我原来的方程也运行良好,但相同的警告锁存问题)

我想一步一步地做一个简单的等式,如下所示:

                             c = 50 / (|a - 2|^2 + |b - 5|^2) 
数据是无符号的二进制32位值,减法结果也是无符号的(绝对值),我要做的是使用时钟分几步执行

       |a - 2| ,               // First this subtraction
       |b - 5| AND |a - 2|^2,  // then a subtraction and a square of before
       |a - 2|^2 + |b - 5|^2   // then the another square plus the before square
       c = 50 / |a - 2|^2 + |b - 5|^2   /// finally a division of 50
我期望的是合成工具在整个过程中只生成一个减法、一个平方和一个除法,在这个简化版本中,这种情况只发生在平方和减法中,因为只有一个除法操作。第一个问题:我真的在做我想做的吗?Quartus II是否生成“数据路径”?硬件/能源是否真正得到了节约

我是verilog和数字设计方面的新手,我自学了这一点,如果我的概念是错误的,请纠正我

我分别创建了除法、减法和平方运算模块,因为我计划以后实现它们,而不是依赖于/、-、*运算符。原因是我可能猜,通过编程更高效的算法(例如,互联网上的作者提供的算法),我可以替代Quartus II中的运算符推断算法。但我还是不确定

这个程序运行正常,输出是预期的,然而,我收到了很多来自Quartus II的警告,就像这样

警告(10240):Verilog HDL始终在FCM_EQ.v(88)处构造警告:推断变量“SU_in_a”的锁存器,该变量通过始终构造在一个或多个路径中保持其以前的值

警告(13012):a[18]中的闩锁SQ_存在不安全行为 警告(13013):闩锁上的端口D和ENA由相同的信号状态供电。S2

我几乎不知道锁存器是什么,我读到一个必须避免锁存器的,是寄存器在不同的时钟中保持它的值吗?整个程序正是关于这一点,所以我不确定如何解决这个问题。有什么建议或替代方案吗

最上面的模块是:

module FCM_EQ (a, b, c, clk, enable, rst_n, all_finish, OBS);

input [31:0] a, b; 
input clk, enable, rst_n; 
output [31:0] c;
output [63:0] OBS;
output all_finish;

reg [31:0] SU_in_a, SU_in_b; 
wire [31:0] SU_out_r;

reg [31:0] SQ_in_a;
wire [63:0] SQ_out_r;

reg [63:0] DIV_in_b;
reg [63:0] DIV_in_a;
wire [63:0] DIV_out_r; 

reg [31:00] botA, botB, c;
reg [63:00] SQ_botA, SQ_botB, N_C;                    
reg [63:0] den_total;

reg all_finish;
reg [4:0] state, nextstate;
reg [63:0] OBS;

parameter FIFTY = 64'b0000000000000000_0000000000110010_0000000000000000_0000000000000000;
parameter FIVE = 32'b0000000000000101_0000000000000000;
parameter TWO = 32'b0000000000000010_0000000000000000;

parameter reset = 0;
parameter S0 = 1;
parameter S1 = 2;
parameter S2 = 3;
parameter S3 = 4;

SUB_VAL SU_inst1(.a (SU_in_a),.b (SU_in_b),.r (SU_out_r) );

SQ_VAL SQ_inst1 (.a (SQ_in_a),.r (SQ_out_r) );

DIV_VAL DIV_inst1 (.a (DIV_in_a),.b (DIV_in_b),.r (DIV_out_r) );

always @ (posedge clk or negedge rst_n)
  if (~rst_n) 
    state <= reset ;
  else
    state <= nextstate; 

always @*
begin
            case (state)    
reset:              
            begin
                if (enable == 1) 
                   nextstate = S0;                  
                else 
                    nextstate = reset;
            end
S0: 
            begin 
                SU_in_a = a;
                SU_in_b = TWO;         
                botA = SU_out_r;                                
                nextstate = S1;
            end
S1:
            begin
                SU_in_a = b;
                SU_in_b = FIVE;         
                botB = SU_out_r;                            

                SQ_in_a = botA;
                SQ_botA = SQ_out_r;
                nextstate = S2;
            end 
S2:
            begin
                SQ_in_a = botB;
                SQ_botB = SQ_out_r;      // SQ_botB is 64 bits (32_32)

                den_total = SQ_botA + SQ_botB;
                den_total = den_total >> 24;            
                nextstate = S3;
            end 
S3: 
            begin
                DIV_in_a = FIFTY;                  
                DIV_in_b = den_total;                 
                N_C = DIV_out_r;                        
                OBS = N_C;
                c = N_C [31:0];     // Extract 32 bits en total (16_24)                 
                all_finish = 1;
                nextstate = reset;
            end

default: 
            begin
                nextstate = reset;
            end
         endcase
 end
 endmodule
模块FCM_EQ(a、b、c、时钟、启用、重新设置、全部完成、OBS);
输入[31:0]a,b;
输入时钟、启用、重新设置;
输出[31:0]c;
输出[63:0]OBS;
输出所有_完成;
reg[31:0]苏英a,苏英b;
导线[31:0]输出;
reg[31:0]平方英寸;
电线[63:0]平方米;
注册[63:0]部门在b;
reg[63:0]分区a;
电线[63:0]分接头;
注册号[31:00]botA,botB,c;
reg[63:00]SQ_botA,SQ_botB,N_C;
注册编号[63:0]总计;
注册所有_完成;
注册[4:0]状态,下一状态;
注册[63:0]OBS;
参数50=64'b0000000000000000\U0000000000 110010\U0000000000000000\U0000000000000000;
参数五=32'b0000000000000101_0000000000000000;
参数二=32'b0000000000000010\U0000000000000000;
参数重置=0;
参数S0=1;
参数S1=2;
参数S2=3;
参数S3=4;
SUB_VAL SU_inst1(.a(SU_in_a),.b(SU_in_b),.r(SU_out_r));
SQ_VAL SQ_inst1(.a(SQ_in_a),.r(SQ_out r));
DIV_VAL DIV_inst1(.a(DIV_in_a),.b(DIV_in_b),.r(DIV_out r));
始终@(posedge clk或negedge rst_n)
如果(~rst_n)
国家24;
nextstate=S3;
结束
S3:
开始
DIV_in_a=50;
DIV_in_b=den_总计;
N_C=DIV_out\r;
OBS=N_C;
c=N_c[31:0];//共提取32位(16_24)
所有表面光洁度=1;
nextstate=重置;
结束
违约:
开始
nextstate=重置;
结束
尾声
结束
端模
OBS寄存器只是我在Modelsim中检查寄存器值的noob方法,因为我忽略了是否有更好的方法来监视它

这里可以看到测试台和完整的代码


不是完整答案,只是快速观察:

always @ (posedge clk)
  state <= nextstate; //Use Non blocking

  always @* // Auto sensitivity list
  begin
    case (state)
始终@(posedge clk)

陈述不是完整答案,只是快速观察:

always @ (posedge clk)
  state <= nextstate; //Use Non blocking

  always @* // Auto sensitivity list
  begin
    case (state)
始终@(posedge clk)

state@sujeto1 EDA游乐场上的代码似乎没有什么不同。您是否发布了正确的URL?@sujeto1在EDA游乐场中使用Verilog,您需要包含任何其他文件。这有点笨重。我想更改它,但还没有想到一种不破坏现有保存代码的方法(我没有创建EDA游乐场,但我现在是负责它的人)。我已经修改了你的代码来完成这项工作-请参阅。它现在可以编译了。子模块的输入应该总是被定义的,您只是在想要使用它们的状态下定义它们。这意味着锁。此外,还有类似于
NSQ\u botA=NSQ\u botA>>24的行,看起来您希望组合逻辑保留状态,或者重用regs来计算临时值。如果不这样做,效果会更好。@sujeto1获得锁存的原因是您的赋值不完整。对于组合逻辑,所有输出(在always块中分配的是所有REG)必须分配通过代码的任何路径。您的代码中没有这种确定性。这个链接是关于VHDL的,但原理是完全相同的:。另外一件事,我看到虽然我的程序给出了正确的答案,但我还是应该修复锁存器的问题,还是可以这样离开它们?@sujeto1 EDA游乐场上的代码似乎没有什么不同。您是否发布了正确的URL?@sujeto1在EDA游乐场中使用Verilog,您需要包含任何其他文件。这有点笨重。我想更改它,但还没有想到一种不破坏现有已保存代码的方法(我没有创建EDA游乐场,bu)