看看这句赋值为什么不可以?(verilog)
input clock,rst;
input [0:7]num;
output divout;
reg [0:7]count_p,count_n,half;
reg freq_p,freq_n;
assign divout=freq_p||freq_n;
initial
begin
half=num;
half=(half>>1);
count_p=0;
count_n=0;
end
这是程序开始的一部分, initial的第一句half=num,仿真的时候始终不可以,总是跳过这里到了下一句的移位。是不是wire不能给reg赋值阿?我用half[7:0]=num[7:0]也不可以,改成非阻塞赋值也不可以。
num是输入的分频倍数,如果这样不可以的话,这里应该怎么写才能使输入的num能存到寄存器half中呢?
[求助]看看这句赋值为什么不可以?(verilog)
贴出全部的程序:
`timescale 1ns/1ns
module freqdiv(clock,num,rst,divout);
input clock,rst;
input [0:7]num;
output divout;
reg [0:7]count_p,count_n,half;
reg freq_p,freq_n;
assign divout=freq_p||freq_n;
initial
begin
half=num;
half=(half>>1);
count_p=0;
count_n=0;
end
always
@(posedge clock)
begin
if (rst)
begin
count_p=0;
count_n=0;
end
else
begin
if(count_p==num-1)
count_p<=0;
else
count_p<=count_p+1;
end
end
always
@(negedge clock)
begin
if (rst)
begin
count_p=0;
count_n=0;
end
else
begin
if(count_n==num-1)
count_n<=0;
else
count_n<=count_n+1;
end
end
always
@(clock)
begin
freq_p<=(count_p<=half)?1:0;
freq_n<=(count_n<=half)?1:0;
end
endmodule
是一个可控分频器。
testbench是
`timescale 1ns / 1ns
module freqdiv_tb;
//Internal signals declarations:
reg clock;
reg [0:7]num;
reg rst;
wire divout;
// Unit Under Test port map
freqdiv UUT (
.clock(clock),
.num(num),
.rst(rst),
.divout(divout));
initial
begin
clock=0;
rst=1;
num=5;
end
always
clock=#10 ~clock;
initial
begin
#30 rst=0;
#300 $stop;
end
initial
$monitor($realtime,,"ns %h %h %h %h ",clock,num,rst,divout);
endmodule
[求助]看看这句赋值为什么不可以?(verilog)
initial
begin
half=num;
half=(half>>1);
count_p=0;
count_n=0;
end
相当于 #0 half=num;half=(half>>1); 就是说在第0个时间单位同时对一个变量赋值两次,以后面一次为准是正常的。
另外,提醒一下,intial块是不可综合的,你最好用其他方法来实现这个功能。
[求助]看看这句赋值为什么不可以?(verilog)
但是我在half=(half>>1)前面加上一个时延,比如#30,依然是不能赋值。:(
而且如果这种类型的语句,不用initial的话,能用什么结构呢?也就是初始时用wire对一个寄存器赋值一次,应该用什么结构呢?
[求助]看看这句赋值为什么不可以?(verilog)
你用什么仿真器仿真的?
如果要硬件实现的话,最好用上电时rst信号给half赋初始值。
[求助]看看这句赋值为什么不可以?(verilog)
也就是说在rst=1时给half赋值吗?
我用的是modelsim5.8c 就是不可以,很头疼。
[求助]看看这句赋值为什么不可以?(verilog)
你如果只是仿真玩的话,改成这样:
initial
begin
#1 half=num;count_p=0;count_n=0;
#30 half=(half>>1);
end
因为你的num也是在0时刻赋值的。
实际用就是在rst=1的时候让half=num;
[求助]看看这句赋值为什么不可以?(verilog)
谢谢楼上的,问题已解决,我把前面的initial改成了这样:
`timescale 1ns/1ns
module freqdiv(clock,rst,num,divout);
input clock,rst;
input [0:7]num;
output divout;
reg [0:7]count_p,count_n,half,all;
reg freq_p,freq_n;
assign divout=freq_p&freq_n;
always@(negedge rst)
begin
all=num;
half=all>>1;
end
这样仿真就可以通过了。
小弟初学verilog,谢谢大哥帮忙!
[求助]看看这句赋值为什么不可以?(verilog)
这个,其实还是不对,会把rst综合成时钟。不过我还是不多说了,你自己摸索一下,慢慢体会吧,有好处的。
[求助]看看这句赋值为什么不可以?(verilog)
改了一下,在rst为高的时候给half赋值
加了一个all寄存器,在中间传递数据。
always
@(posedge clock)
begin
if (rst)
begin
all=num;
half=all>>1;
count_p=0;
count_n=0;
end
else
begin
if(count_p==num-1)
count_p<=0;
else
count_p<=count_p+1;
end
end
正在学习综合,刚开始。
小编能给推荐一个中文的综合的初级教程吗?主要是没有方向:)
因为阻塞式赋值是顺序执行的,所以你的initial块的前两条语句等效于:Half = num[1:7]。
[求助]看看这句赋值为什么不可以?(verilog)
楼上的每明白我的意思,我的意思是half=num这句没有执行。
[求助]看看这句赋值为什么不可以?(verilog)
改成half<=num试试
[求助]看看这句赋值为什么不可以?(verilog)
还是不可以。你可以看看上面的讨论,各种方法都试过了。呵呵,这个问题的确要慢慢体会:)
[求助]看看这句赋值为什么不可以?(verilog)
小编主要是对verilog不熟造成的误会。
从你的开始到后来的改动,你可以体会到:
1.initial里对一个变量是顺序赋值的,并且要有延迟来控制时序。
2.需要寄存的信号,必须在always里用寄存器来锁存。
[求助]看看这句赋值为什么不可以?(verilog)
谢谢楼上的帮助,我写这个程序的确有很多的心得。
[求助]看看这句赋值为什么不可以?(verilog)
1。在实现的module里,不要出现不可综合的语句,象initial,repeat等。
2。一个reg不要在多个always语句里重复赋值,象count_p和count_n。
3。一个比较好的同步逻辑的写法是这样的:
parameter udly = 1;
always@(posedge clock or negedge rst_)//rst_下划线代表低电平有效。
if(!rst_)
count_n <= #udly 'h0;
else if(count_n==num-1)
count_n <= #udly 'h0;
else if(enable)//加上一个enable信号
count_n <= #udly count_n + 1'b1;
4。同步逻辑:尽量不要出现用clock的上升沿和下升沿同时触发的always,
尽量在一个design里应用相同的沿触发条件。
5。多注意点 HDL coding的 style。
[求助]看看这句赋值为什么不可以?(verilog)
感谢呀!说的真是太中肯了。谢谢!