fpga新手请教,verilog代码问题~~~
本帖最后由 fpgaw 于 2010-7-13 13:40 编辑记得在书上看到过这样一段代码:
task shift_in;
output shift;
begin
@(posedge scl) shift=sda;
@(posedge scl) shift=sda;
@(posedge scl) shift=sda;
@(posedge scl) shift=sda;
@(posedge scl) shift=sda;
@(posedge scl) shift=sda;
@(posedge scl) shift=sda;
@(posedge scl) shift=sda;
@(negedge scl)
begin
#`timeslice;
out_flag=1;
sda_buf=0;
end
@(negedge scl)
#`timeslice out_flag=0;
end
endtask
这是在不可综合的行为模块中的代码,我想请问这段代码的执行是串行还是并行呢??这段代码的如果把赋值号改成非阻塞式的应该就是并行执行的吧~~shift到shift都应该是相同的值了。
谢谢各位高手帮忙解答 我个人理解是这时 阻塞非阻塞结果一致。<br>
你还是仿真一下看看。 仿真看一下不就知道了嘛,呵呵 我仿真过的,结果是这几条语句是同时执行的,但是我觉得奇怪,为什么在夏老实书上182页的一个行为模块里它似乎又是按节拍来执行的~~糊涂了 这个应该是I2C模块模型的一个TASK, 是8位数据接收的任务模块, 是串行输入, 并且有起始位和停止位<br>
<br>
这个模块中在每个SCL 的上升沿收集一次数据. 加上停止位,共9bit<br>
<br>
仿真的时候注意一下技巧,代码没问题的 恩恩,楼上说的对,我也仿真过了,代码确实没有问题<br>
但是我想把类似语句借用到我的模块里就发生时序不对的问题了<br>
这几个语句是并行执行的~~ 那把你模块里的代码贴出来看看,<br>
有些时候不起眼的地方的区别,<br>
影响却很大 恩恩,好的~~我写了个SPI的从模块,受单片机控制,现在只想最先实现对16位数据的收发,写先写地址,再读写数据,地址的首位表示读或者写,但是我的时序老是有问题,请各位高手指教~~!!<br>
module my_spi_sm(<br>
reset, //system reset<br>
ste, //enable the spi_sm to work<br>
sclk, <br>
simo, <br>
somi,<br>
crdata,<br>
cwdata,<br>
caddr<br>
);<br>
input reset,sclk,ste;<br>
input simo;<br>
output somi;<br>
input crdata;<br>
output cwdata;<br>
output caddr;<br>
<br>
reg ff;<br>
reg somi;<br>
reg data_in;<br>
reg data_out;<br>
<br>
<br>
reg data_write;<br>
reg crnw; //read/1 or write/0 enable <br>
reg caddrh;<br>
reg caddrl;<br>
reg caddrh_ready;<br>
reg caddrl_ready;<br>
reg cdatah_ready;<br>
reg cdatal_ready;<br>
reg main_state;<br>
reg sh8in_state;<br>
reg sh8out_state;<br>
<br>
assign caddr=caddrl_ready?{1'b1,caddrh,caddrl}:16'h0000;<br>
assign cwdata=cdatal_ready?data_write:16'h0000;<br>
<br>
//-----------------------------parameters--------------------------------------------------<br>
parameter <br>
idle =7'b0000001,<br>
write_addrh =7'b0000010,<br>
write_addrl =7'b0000100,<br>
write_datah =7'b0001000,<br>
write_datal =7'b0010000,<br>
read_datah =7'b0100000,<br>
read_datal =7'b1000000;<br>
<br>
parameter<br>
sh8in_bit7=8'b00000001,<br>
sh8in_bit6=8'b00000010,<br>
sh8in_bit5=8'b00000100,<br>
sh8in_bit4=8'b00001000,<br>
sh8in_bit3=8'b00010000,<br>
sh8in_bit2=8'b00100000,<br>
sh8in_bit1=8'b01000000,<br>
sh8in_bit0=8'b10000000;<br>
<br>
parameter<br>
sh8out_bit7=8'b00000001,<br>
sh8out_bit6=8'b00000010,<br>
sh8out_bit5=8'b00000100,<br>
sh8out_bit4=8'b00001000,<br>
sh8out_bit3=8'b00010000,<br>
sh8out_bit2=8'b00100000,<br>
sh8out_bit1=8'b01000000,<br>
sh8out_bit0=8'b10000000;<br>
<br>
<br>
<br>
//--------------------------main state machine----------------------------------------<br>
<br>
always@(posedge sclk or posedge reset)<br>
if(reset)<br>
begin<br>
ff <= 0;<br>
caddrh <= 0;<br>
caddrl <= 0;<br>
caddrh_ready <= 0;<br>
caddrl_ready <= 0;<br>
cdatah_ready <= 0;<br>
cdatal_ready <= 0; <br>
<br>
main_state <=idle;<br>
end <br>
else<br>
begin<br>
casex(main_state)<br>
idle: begin <br>
ff <=0;<br>
caddrh_ready <= 0;<br>
caddrl_ready <= 0;<br>
cdatah_ready <= 0;<br>
cdatal_ready <= 0; <br>
if(ste==0)<br>
begin<br>
main_state <=write_addrh;<br>
sh8in_state<=sh8in_bit7;<br>
end<br>
else<br>
main_state <=idle;<br>
end<br>
write_addrh:<br>
if(ff==0)<br>
shift8_in;<br>
else<br>
begin<br>
crnw <=data_in;<br>
caddrh<=data_in;<br>
caddrh_ready <=1;<br>
main_state <=write_addrl;<br>
ff <=0;<br>
end<br>
write_addrl:<br>
if(ff==0)<br>
shift8_in;<br>
else<br>
begin<br>
ff <=0;<br>
caddrl_ready <=1;<br>
caddrl <=data_in;<br>
if(crnw==1)<br>
begin<br>
main_state<=read_datah;<br>
sh8out_state<=sh8out_bit7;<br>
data_out<=crdata;<br>
end<br>
else <br>
begin<br>
main_state<=write_datah;<br>
end<br>
end<br>
<br>
write_datah:<br>
if(ff==0)<br>
shift8_in;<br>
else<br>
begin<br>
data_write<=data_in;<br>
cdatah_ready<=1; <br>
main_state<=write_datal;<br>
ff<=0;<br>
end<br>
write_datal:<br>
if(ff==0)<br>
shift8_in;<br>
else<br>
begin<br>
data_write<=data_in;<br>
cdatal_ready<=1;<br>
main_state<=idle;<br>
ff<=0;<br>
end<br>
read_datah: <br>
if(ff==0)<br>
shift8_out;<br>
else<br>
begin<br>
data_out<=crdata;<br>
main_state<=read_datal;<br>
ff<=0;<br>
end<br>
read_datal:<br>
if(ff==0)<br>
shift8_out;<br>
else<br>
begin<br>
main_state<=idle;<br>
ff<=0;<br>
end<br>
default: main_state<=idle;<br>
endcase<br>
end<br>
<br>
<br>
<br>
//--------------------------shift in bit by bit---------------------------------------- <br>
task shift8_in;<br>
begin<br>
casex(sh8in_state) <br>
sh8in_bit7: if(!sclk)<br>
begin<br>
data_in<=simo;<br>
sh8in_state<=sh8in_bit6;<br>
end<br>
else<br>
sh8in_state<=sh8in_bit7; <br>
sh8in_bit6: if(!sclk)<br>
begin<br>
data_in<=simo;<br>
sh8in_state<=sh8in_bit5;<br>
end<br>
else<br>
sh8in_state<=sh8in_bit6;<br>
sh8in_bit5: if(!sclk)<br>
begin<br>
data_in<=simo;<br>
sh8in_state<=sh8in_bit4;<br>
end<br>
else<br>
sh8in_state<=sh8in_bit5;<br>
sh8in_bit4: if(!sclk)<br>
begin<br>
data_in<=simo;<br>
sh8in_state<=sh8in_bit3;<br>
end<br>
else<br>
sh8in_state<=sh8in_bit4;<br>
sh8in_bit3: if(!sclk)<br>
begin<br>
data_in<=simo;<br>
sh8in_state<=sh8in_bit2;<br>
end<br>
else<br>
sh8in_state<=sh8in_bit3;<br>
sh8in_bit2: if(!sclk)<br>
begin<br>
data_in<=simo;<br>
sh8in_state<=sh8in_bit1;<br>
end<br>
else<br>
sh8in_state<=sh8in_bit2; <br>
sh8in_bit1: if(!sclk)<br>
begin<br>
data_in<=simo;<br>
sh8in_state<=sh8in_bit0;<br>
end<br>
else<br>
sh8in_state<=sh8in_bit1; <br>
sh8in_bit0: if(!sclk)<br>
begin<br>
data_in<=simo;<br>
sh8in_state<=sh8in_bit7;<br>
ff<=1;<br>
end<br>
else<br>
sh8in_state<=sh8in_bit0;<br>
default: <br>
begin<br>
ff<=0;<br>
sh8in_state<=sh8in_bit7;<br>
end<br>
endcase<br>
end<br>
endtask<br>
<br>
//--------------------------shift out bit by bit---------------------------------------- <br>
task shift8_out;<br>
begin<br>
casex(sh8out_state)<br>
sh8out_bit7:<br>
if(sclk)<br>
begin<br>
somi<=data_out;<br>
sh8out_state<=sh8out_bit6;<br>
end<br>
else<br>
sh8out_state<=sh8out_bit7;<br>
sh8out_bit6:<br>
if(sclk)<br>
begin<br>
somi<=data_out;<br>
sh8out_state<=sh8out_bit5;<br>
end<br>
else<br>
sh8out_state<=sh8out_bit6;<br>
sh8out_bit5:<br>
if(sclk)<br>
begin<br>
somi<=data_out;<br>
sh8out_state<=sh8out_bit4;<br>
end<br>
else<br>
sh8out_state<=sh8out_bit5;<br>
sh8out_bit4:<br>
if(sclk)<br>
begin<br>
somi<=data_out;<br>
sh8out_state<=sh8out_bit3;<br>
end<br>
else<br>
sh8out_state<=sh8out_bit4;<br>
sh8out_bit3:<br>
if(sclk)<br>
begin<br>
somi<=data_out;<br>
sh8out_state<=sh8out_bit2;<br>
end<br>
else<br>
sh8out_state<=sh8out_bit3;<br>
sh8out_bit2:<br>
if(sclk)<br>
begin<br>
somi<=data_out;<br>
sh8out_state<=sh8out_bit1;<br>
end<br>
else<br>
sh8out_state<=sh8out_bit2;<br>
sh8out_bit1:<br>
if(sclk)<br>
begin<br>
somi<=data_out;<br>
sh8out_state<=sh8out_bit0;<br>
end<br>
else<br>
sh8out_state<=sh8out_bit1;<br>
sh8out_bit0:<br>
if(sclk)<br>
begin<br>
somi<=data_out; <br>
sh8out_state<=sh8out_bit7;<br>
ff<=1; <br>
end<br>
else<br>
sh8out_state<=sh8out_bit0;<br>
<br>
default: <br>
begin<br>
ff<=0;<br>
sh8out_state<=sh8out_bit7;<br>
end<br>
endcase<br>
end<br>
endtask <br>
<br>
<br>
endmodule 楼主,无论什么语句,只要在begin-end中的语句都是顺序执行的。behavior里面根据我的经验是不用<=这样的表达式,因为很容易混淆,而且也完全没有必要。<br>
你的task里面用=和用<=的区别对于task本身来讲区别不大,因为都可以通过这个task接受到一个有效的byte,但是如果同时其他信号有用到你sample的值,比如在第一个clk之后sample shift,如果用=(立即update值),那么就可以sample到第一个sda值,而如果用<=(等待delta时间update值),就无法sample到。<br>
你可加一段debug程序:<br>
initial<br>
begin<br>
@(posedge clk) sample = shift // 有可能要加条件以使得和task里面第一个clk同时发生<br>
$display(......);<br>
end<br>
看看结果 非常感谢 !!
页:
[1]
2