微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 请问 Verilog 高手语法与ModelSim 问题?

请问 Verilog 高手语法与ModelSim 问题?

时间:10-02 整理:3721RD 点击:
always @(posedge clk)                                                                     
begin                                                                                    
//  c16  <= ~c16;  这样写编辑ok,但是ModelSim 仿真不了?                                                                  
  if (c16 == 1'b1)
      c16 <= 1'b0;
  else
      c16 <= 1'b1;   
end

那肯定,时钟都没用进去,还是先把语法搞清楚再写吧,这是最简单的。

把复位加上,初态都没有,怎么取反输出啊。
always @(posedge clk or posedge rst)                                                                  
begin
     if (rst)
         c16   <= 1'b0;
     else                                                                                    
   c16  <= ~c16;
end

编辑器测试OK,实际2种方式也正常,唯独 ModelSim不允许使用 c16  <= ~c16 ?不知道ModelSim 那里可设定Verilog2005?

你可以使用 ISE 或是 Quartus 测试看看不用RST,工作正常,但是唯独 ModelSim 动作异常?

应当是modelsim的版本或者其选择的verilog版本的问题,老版本的verilog里面,没有~操作符。

我目前使用的是 Modelsim SE 10.1c 因该有,但是不知道怎么加载进去?


     ISE或者QUARTUS II,都会有自动全局复位模式的,开始跑之前,会把所有信号没复位的信号都拉到0。这跟SOF在硬件上跑是一样的。
     MODELSIM 不会有这个过程。 你要不加个initial语句给C16一个初值,要么加个复位。C16的初始值都没有,就是个不定态,你就让它自己对自己取反,那输出的就是不定态。你自己稍微想想就想通了。语法先搞清楚。

但是为什么我改成这样ModelSim就可以?C16 也不用给任何值?
if (c16 == 1'b1)
      c16 <= 1'b0;
  else
      c16 <= 1'b1;   
   



     当然了,改成if - else以后就有值了。if (c16为1)的时候,给c16拉到0;else (其他任何状态,包括不定态),给c16赋值1。



所以不加 RST或是 c16默许值也没关系.但是我目前是c16  <= ~c16; 这个问题阿?
c16  <= ~c16 為什麼ModelSim 動不了,ISE 與 Quartus 实际动作都正常? ModelSim 也没说语法错误阿?


实际中上电的时候总有个固定值。
仿真时必须要有初始条件,否则结果未知,if else的写法隐藏着初始化条件,否则加复位信号吧。

这样的语法 ModelSim 也不行?
always @(posedge CLK)                                                                  
begin                                                                                    
  c33[0]   <= (c33[1:0]==2'b00);                                                         
  c33[2:1] <= c33[1:0];                                                                  
end

多看点基本语法书挺好

目前是 Verilog 版本问题,以前的基本语法不可以,现在已经改了.

    大哥,verilog描述的是硬件,别用软件方法写代码

1. module中把C16声明为reg类型的。
2. testbench中给C16赋初值:
initial                                                
begin                                                  
    C16 = 0;
end

    这正说明你在modelsim中没有为c16赋初值。c16初值不定时,条件(c16 == 1'b1)不成立,c16<=1'b0语句执行了,以后c16就有确定值了。但是c16<=~c16语句永远不会产生确定的值。软件设计语言C/C++中的变量的某位,非0即1。但是HDL中有0、1、x、z。

所以ModelSim仿真与实际是不一样的,实际 c16<=~c16 只有"0"与"1"状态,不会有 x`z.状态.
那么ModelSim仿真软体就不准了.

    你说的不正确。ModelSim是为了保证你设计的代码的健全,设计可预知。电子电路中有些电平处于临界状态,有时是0,有时是1。例如:某系统(器件)0~1.7v为低电平‘0’,2.5~5v为高电平'1'。当你输入2.0v电压时,就是临界状态。你这次开机是0,下次开机就可能是1。


加入 RST_N 正常,但是如果使用 Quartus II 运行 ModelSim 就会错误?
Error: ModelSim Error: # ** Error: c:/altera/12.1/quartus/eda/sim_lib/cycloneii_atoms.v(5354): $hold( posedge clk &&& sloaddata:252877 ps, sdata:252972 ps, 266 ps );


Quartus,你可以这样试一试:
菜单Settings...->Device(左)->Devive and pin options按钮(右)->General选卡,选择“Enable device-wide reset(DEV_CLRn)”。这样做了,能保证实际电路的时序逻辑有确定的初值。ModelSim的Gate Level仿真可能OK了。RTL仿真,testbench中还是要设初值。不同PLD厂家区别吧。我也学习到了知识。

else 里面包括不定态,所以写if else 会有输出,我觉得还是没有复位的问题,



   这个是时序上面的问题,保持时间不够

谢谢说明
可是 QuartusII 仍然无法使用 ModelSim仿真,我并没有使用 Quartus 任何一个IP元件,不知道是否是 Quartus 12.1有问题.
但是我其他范例有使用 Quartus IP 的范例运行都正常?

已经实际验证过了,仿真如果没有 RESET_N 初始化无法仿真,但是如果编程进去 FPGA 既使没有 RESET_N 也可以运行正确.

把调用vlog的命令行贴出来看看?

使用 Quartus II 运行 ModelSim 就会错误?
"Cyclone II"
DEVICE EP2C70F896C6
Quartus II 12.1
tp_clk_tb.v
module tp_clk_tb;
reg  rst_n;
reg  clk;
wire [2:0] a;
wire       b;
wire       c;
wire       d;
tp_clk   u0 (
   .RST_N(rst_n),
   .CLKIN(clk),
   .a(a),
   .b(b),
   .c(c),
   .d(d)
);
parameter clkper = 100;      
initial begin
   clk   = 1'b0;
end
always begin
   #(clkper / 2) clk = ~clk;  
end
initial begin
rst_n = 1'b0;
#225;
rst_n = 1'b1;
#100;
#100;
#100;
#100;
#100;
end
endmodule
=============================================
tp_clk.v
module tp_clk(                                                                           
              RST_N,
              CLKIN,                                                                     
              a,                                                                        
              b,                                                                        
              c,                                                                        
              d                                                                          
             );                                                                          
                                                                                         
input  RST_N;
input  CLKIN;                                                                           
output [2:0] a;                                                                          
output b;                                                                                
output c;                                                                                
output d;                                                                                
                                                                                         
                                                                                         
reg [2:0] c33;                                                                           
reg c31;                                                                                 
always @(posedge CLKIN or negedge RST_N )
begin                                                                                    
  if (!RST_N)
         c33 <= 3'b000;
  else
     begin
         c33[0]   <= (c33[1:0]==2'b00);                                                         
         c33[2:1] <= c33[1:0];                                                                  
     end
end                                                                                      
                                                                                         
reg c16,c16n;                                                                           
always @(posedge b or negedge RST_N)
begin                                                                                    
  if (!RST_N)
     begin
         c16n <= 1'b0;
         c16  <= 1'b0;
     end
  else
     begin
         c16n <= c33[1];                                                                        
         c16  <= ~c16;                                                                          
     end
end                                                                                      
                                                                                         
always @(negedge CLKIN or negedge RST_N)
       begin
          if (!RST_N)
             c31 <= 1'b0;
          else                    
             c31 <= c33[1];
       end
                                                                                 
assign a = c33;                                                                          
assign b = c33[0] | c31;                                                                 
assign c = c16;                                                                          
assign d = c16n;                                                                        
endmodule

    看不出代码有什么大问题,似乎不会出现图中的问题。不过请你这样试一试:在第一个always之前加上三行,
wire  [1:0] c33q;                                                                           
buf   i0buf(c33q[0], c33[0]);                                                                  
buf   i1buf(c33q[1], c33[1]);                                                                  
然后,把第一个always中的c33[0]<= (c33[1:0]==2'b00);改为,
c33[0] <= (c33q[1:0]==2'b00);
这样做的目的是把c33[1:0]在反馈到输入前人为的延时。

谢谢
试了一下~不行..
Quartus II 12.1與 10.1  仍然出现相同的错误ModelSim 无法使用.

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top