|
|||||||||||
| 技術交流 | 電路欣賞 | 工控天地 | 數字廣電 | 通信技術 | 電源技術 | 測控之家 | EMC技術 | ARM技術 | EDA技術 | PCB技術 | 嵌入式系統(tǒng) 驅動編程 | 集成電路 | 器件替換 | 模擬技術 | 新手園地 | 單 片 機 | DSP技術 | MCU技術 | IC 設計 | IC 產業(yè) | CAN-bus/DeviceNe |
verilog學習中,碰到問題請指教 |
| 作者:chaojijing 欄目:EDA技術 |
下面的程序用Synplify pro7.7綜合不對,請大蝦門幫看看。里面的脈沖發(fā)生部分倒是沒多大問題,用modelsim仿真波形也基本對的,但是回波部分完全不對,我搞不懂 /*程序的功能是用40M晶振產生10us脈寬的脈沖,周期為10ms。(用mcount1) 并且在10us脈沖的上升沿到來的時候,開始計時。(用mcount2) 計時開始后的任意時刻mget如果有上升沿到來,就停止計時,計時值送入寄存器rega保存,mcount2清0*/ MODULE maichong(mout,mclk,mget); input mclk,mget; //晶振輸入 OUTPUT mout; //脈沖輸出 reg mout; reg[18:0] mcount1; //19位計數器計數值暫存 reg[8:0] mcount2,rega; //9位計數器計數值暫存 always@(posedge mclk) begin if(mcount1<400000) //如果計時時間在400000*25ns=10ms以內 begin mcount1=mcount1+1; //計數 if(mcount1<=400) mout=1; //如果計時時間在400*25ns=10us以內,出脈沖 else mout=0; //如果在10us-10ms以內,脈沖停止 end else mcount1=0; //如果時間出了10ms,對計數器清0 end always@(posedge mclk or posedge mout or posedge mget) begin if(mget)//如果有回波 begin rega=mcount2; //計時時間保存 mcount2=0; //計數器清0 end else //如果沒有回波 begin if(mout) mcount2=mcount2+1; //如果10us脈沖的上升沿到來,開始計時 else mcount2=0; end end endMODULE |
| 2樓: | >>參與討論 |
| 作者: wqi1012 于 2005/2/3 15:50:00 發(fā)布:
程序有錯! always@(posedge mclk or posedge mout or posedge mget) 這一行有問題! 在一個always中不能同時又三個posedge,把一個條件寫到里面應該就行了! |
|
| 3樓: | >>參與討論 |
| 作者: chaojijing 于 2005/2/3 15:53:00 發(fā)布:
啊 "在一個always中不能同時又三個posedge"這是語法規(guī)定馬? 我得書上沒說啊 always不能嵌套吧,那如何寫道里面那? |
|
| 4樓: | >>參與討論 |
| 作者: wqi1012 于 2005/2/3 16:03:00 發(fā)布:
回復 你可以從硬件角度想想,兩個posedge是一個clk和一個reset,我記得3個posedge是不可綜合的。 我說的不是將always嵌套,是將一個posedge當作條件寫在里面! |
|
| 5樓: | >>參與討論 |
| 作者: chaojijing 于 2005/2/3 16:14:00 發(fā)布:
Synplify pro7.7可以綜合 但是結果不對,脈沖產生電路是有的,但是第二個always塊沒有產生任何RTL電路,mget就一個空的腳在那里 poedge mout刪去也不行,一樣.你的意思是不是下面這樣 always@(posedge mclk or posedge mget) begin if(mget)//如果有回波 begin rega=mcount2; //計時時間保存 mcount2=0; //計數器清0 end else //如果沒有回波 begin if(mout) mcount2=mcount2+1; //如果10us脈沖的上升沿到來,開始計時 else mcount2=0; end end |
|
| 6樓: | >>參與討論 |
| 作者: wqi1012 于 2005/2/3 16:44:00 發(fā)布:
拆 要不你就把第二個always 拆成兩個。 一個生成rega,另一個計數。 計數的用mout當時鐘。 |
|
| 7樓: | >>參與討論 |
| 作者: chaojijing 于 2005/2/3 17:00:00 發(fā)布:
mout不能當時鐘的 mout的上升沿表示開始計數,計數時鐘還是mclk的 怎么拆,我是新手,想不出來啊.... |
|
| 8樓: | >>參與討論 |
| 作者: xjg1111 于 2005/2/3 17:18:00 發(fā)布:
re always@(posedge mclk or posedge mout or posedge mget) begin if(mget)//如果有回波 begin rega=mcount2; //計時時間保存 mcount2=0; //計數器清0 end else //如果沒有回波 begin if(mout) mcount2=mcount2+1; //如果10us脈沖的上升沿到來,開始計時 else mcount2=0; end end endmodule 這段程序是不可綜合的, 多于一個時鐘源的都是不可綜合的,你這段程序中mget會被綜合為復位端。 但還是有兩個時鐘源,還有,將代碼改成非阻塞觸發(fā)的方式,會好些。 你檢測上升沿可以用移位來做,40M的時鐘檢測10U的上升沿完全可以, |
|
| 9樓: | >>參與討論 |
| 作者: wqi1012 于 2005/2/3 17:18:00 發(fā)布:
回復 對不起,剛才我說的好像有點問題! 我按照我的理解把你的程序從寫了一下: /*程序的功能是用40M晶振產生10us脈寬的脈沖,周期為10ms。(用mcount1) 并且在10us脈沖的上升沿到來的時候,開始計時。(用mcount2) 計時開始后的任意時刻mget如果有上升沿到來,就停止計時,計時值送入寄存器rega保存,mcount2清0*/ MODULE maichong(mout,mclk,mget); input mclk,mget; //晶振輸入 OUTPUT mout; //脈沖輸出 reg mout; reg[18:0] mcount1; //19位計數器計數值暫存 reg[8:0] mcount2,rega; //9位計數器計數值暫存 always @(posedge mclk) begin if (mcount1<400000) mcount1 <= mcount1 + 1; else mcount1 <= 0; end always @(posedge mclk) begin if (mcount1<=400) mout <= 1; else mout <= 0; end always @(posedge mclk or posedge mget) begin if (mget) rega <= mcount2; else rega <= rega; always @(posedge mclk or posedge mget) begin if (mget) mcount2 <= 0; else if (mout) mcount2 <= mcount2 + 1; else mcount2 <= 0; end endMODULE 你看看有沒有好點! |
|
| 10樓: | >>參與討論 |
| 作者: chaojijing 于 2005/2/3 17:30:00 發(fā)布:
不行啊555 還是一樣,mget依舊是空的 還有 always @(posedge mclk or posedge mget) begin if (mget) rega <= mcount2; always @(posedge mclk or posedge mget) begin if (mget) mcount2 <= 0; 因為always塊并行執(zhí)行的,這兩句會不會有沖突呢,會不會先清0了而沒把計數值送入rega呢? 你用你的Synplify綜合試試看,看是不是我得Synplify的問題 * - 本貼最后修改時間:2005-2-3 17:45:10 修改者:chaojijing
|
|
| 11樓: | >>參與討論 |
| 作者: wqi1012 于 2005/2/3 18:31:00 發(fā)布:
DC也不行 應該不是工具的問題,我拿dc試,好像也不行! |
|
| 12樓: | >>參與討論 |
| 作者: wqi1012 于 2005/2/3 22:02:00 發(fā)布:
初值! 我想可能是你mcount1沒有初值,mcount1的值始終是花的,沒有值! 所以,mout始終是0,下面這段程序: always @(posedge mclk or posedge mget) begin if (mget) mcount2 <= 0; else if (mout) mcount2 <= mcount2 + 1; else mcount2 <= 0; end 會優(yōu)化成mcount2始終為零。mget沒有用! 你在mcount1加一個復位端,賦個初值試試! 我也是猜,你先試試! |
|
| 13樓: | >>參與討論 |
| 作者: chaojijing 于 2005/2/3 22:26:00 發(fā)布:
呵呵,非常感謝 這么晚還在關注我得帖子,真是認真的人 今天沒法試了,明天去公司試下 我一直以為初始都是為0的呢,而我又不需要復位端,所以就沒加。那如果加了復位端,那我在實際器件上如何處理這個腳比較好? |
|
| 14樓: | >>參與討論 |
| 作者: wqi1012 于 2005/2/4 9:54:00 發(fā)布:
mout的問題! 我找到原因了,你把mout的輸出去掉就行了! 器件內部沒有初始化的狀態(tài)是不定的,最好有個初始復位! 對于“那如果加了復位端,那我在實際器件上如何處理這個腳比較好?”我沒法給你建議,fpga我沒做過! |
|
| 15樓: | >>參與討論 |
| 作者: chaojijing 于 2005/2/4 10:07:00 發(fā)布:
去掉是什么意思?還能實現(xiàn)我想要的功能嗎? 能不能把綜合成功的源代碼貼出來看看? 還有如何做初始復位?我確實想讓計數器初值為0的,現(xiàn)在頭腦比較亂,能說說嗎 |
|
| 16樓: | >>參與討論 |
| 作者: wqi1012 于 2005/2/4 10:35:00 發(fā)布:
ok! 如果你真需要mout那就改成這樣! 順便我把rega也輸出了! /*程序的功能是用40M晶振產生10us脈寬的脈沖,周期為10ms。(用mcount1) 并且在10us脈沖的上升沿到來的時候,開始計時。(用mcount2) 計時開始后的任意時刻mget如果有上升沿到來,就停止計時,計時值送入寄存器rega保存,mcount2清0*/ MODULE maichong(mclk,mget,rst,rega,mout); input mclk,mget,rst; //晶振輸入 OUTPUT rega; OUTPUT mout; // OUTPUT mout; //脈沖輸出 // reg mout; reg[18:0] mcount1; //19位計數器計數值暫存 reg[8:0] mcount2,rega; //9位計數器計數值暫存 always @(posedge mclk or posedge rst) begin if (rst) mcount1 <= 0; else if (mcount1<400000) mcount1 <= mcount1 + 1; else mcount1 <= 0; end wire mout = mcount1<=400; always @(posedge mclk or posedge mget) begin if (mget) rega <= mcount2; else rega <= rega; end always @(posedge mclk or posedge mget) begin if (mget) mcount2 <= 0; else if (mout) mcount2 <= mcount2 + 1; end endMODULE 我用dc綜合通過! |
|
| 17樓: | >>參與討論 |
| 作者: chaojijing 于 2005/2/4 10:53:00 發(fā)布:
呼,好多問題想請教你 綜合出來mget確實進去了,脈沖也對,可是為什么mcount1在262143后面就變成了-262144,后面也都是這種負數,怎么回事? 還有一些其他問題,能加你QQ問問嗎?我得8121670 |
|
| 18樓: | >>參與討論 |
| 作者: wqi1012 于 2005/2/4 11:41:00 發(fā)布:
符號! 可能是這樣:262143換成16進制是3ffff,19位計數器滿值是7ffff。 當從3ffff進位時,把最高位認成符號位,那就全負了! 可以把你的mcount1再擴一位,就行了! 我公司上不了qq,抱歉! |
|
| 19樓: | >>參與討論 |
| 作者: chaojijing 于 2005/2/4 11:59:00 發(fā)布:
555為什么啊為什么 各個fpga論壇都死氣沉沉,十幾個EDA QQ群也沒人說話的,好不容易碰到你又上不了QQ,真是郁悶 那只好在這里問了,問題一大堆,只能麻煩你了,先謝謝了] 1、我得程序不行的最根本的錯誤是什么呢? 2、多加一位確實可以了,但是為什么它會自動認最高位位符號位?能不能設定mcount1為無符號整形變量呢? 3、always @(posedge mclk or posedge rst) begin if (rst) mcount1 <= 0; 這句是給mcount1初始化為0的嗎?上電后如果rst腳沒有任何連接(或沒有信號給它)它也是不定的吧,那為什么這句可以給計數器置初值為0呢? 4、always @(posedge mclk or posedge mget) begin if (mget) rega <= mcount2; else rega <= rega; end always @(posedge mclk or posedge mget) begin if (mget) mcount2 <= 0; else if (mout) mcount2 <= mcount2 + 1; end 這兩個always的觸發(fā)條件是一樣的,為什么不會有時序問題?會不會先把mcount2清0了而沒有把它的值送入rega呢? 5、modelsim里面如何設置mget的波形?mclk我會設,只要設置clock就可以,這樣我現(xiàn)在只能仿真出mcount1,而mcount2后面的功能因為不知道怎么給mget所以沒法看,暫時還不知道接收功能是否正常 |
|
| 20樓: | >>參與討論 |
| 作者: wqi1012 于 2005/2/4 13:11:00 發(fā)布:
答 我只在21ic注冊了,別處我也不太清楚! 1,mout本身就不用設置成寄存器,可能就是這里的問題。具體我也沒想特清楚! 2,出現(xiàn)負數,應該是軟件仿真的問題,硬件是不會認識正負數的。 3,如果rst不接,在仿真時,可能會是花的,但在實際中如果不接會有確定值,可能使0也可能是1。 所以,如果有rst,就必須有確定值,否則其不到賦位的作用。 4,不會用沖突,因為是非阻塞賦值,具體你可以看看非阻塞賦值的定義。 5,modelsim理由對線輸入的賦值,還像是限定義一根線,在手動載波形上拉成高低脈沖,應該和時鐘的定義一樣!我還是3年前用的,既不清了! |
|
| 21樓: | >>參與討論 |
| 作者: chaojijing 于 2005/2/4 14:29:00 發(fā)布:
哦 1、應該還不是這個原因,我把我得程序的mout改為wire型的就還是不行 3、那就是說凡是要用計數器的地方,非得加一個外面的腳,而且這個腳還必須有信號給它啊,暈 4、非阻塞賦值的區(qū)別我看了好幾遍了,對a<=b,b<=c這樣簡單的還是能明白,一到程序里就暈了,哎,麻煩 還有個問題,我用modelsim仿真發(fā)現(xiàn)這個程序還是沒實現(xiàn)預期的功能,但是到底那里不對我還沒想出來,我繼續(xù)想中...... |
|
| 22樓: | >>參與討論 |
| 作者: chaojijing 于 2005/2/4 15:07:00 發(fā)布:
看圖說話 如圖,modelsim仿真出來的,mout發(fā)出的時候計數,到mget來的時候停止,這段正確,但是mget消失的時候又開始計數,直到mout消失,我想這是if(mout)這句的毛病把,這句是不是只要mout為高電平就會計數,而不是在mout上升沿計數了 還有那個圖上mget為高電平期間計數為0的,我想也是if(mget)這句起的作用吧,怎么解決呢本來我想做沿判斷的變成了電平判斷......
|
|
| 23樓: | >>參與討論 |
| 作者: wqi1012 于 2005/2/4 15:49:00 發(fā)布:
你的設計思想到底是什么? 在有mget的時候置rega,并請mcount2,然后呢? 在你原來程序里寫的就是在沒有mget,并且有mout的時候mcount2計數。 如果想在第一個mget的上升沿后,mcount2不再計數,可以這樣: 定義一個新的信號stop reg stop; always @(posedge mclk) if(mget)stop <=1; always @(posedge mclk) begin if (stop) mcount2 <= 0; else if (mout) mcount2 <= mcount2 + 1; end |
|
| 24樓: | >>參與討論 |
| 作者: chaojijing 于 2005/2/4 16:51:00 發(fā)布:
不行啊 由于stop初始是不定的,所以仿真時mout出現(xiàn)的時候并沒有開始計數,而我加入rst也不行 eg mcount2_stop; always @(posedge mclk or posedge mget or posedge rst) begin if(rst) mcount2_stop<=0; else if(mget) mcount2_stop <=1; end 另外光加入stop也不行吧,由于stop得到1后不再改變,那以后再來mout的時候mcount2也不會再計數了啊 * - 本貼最后修改時間:2005-2-4 16:54:05 修改者:chaojijing
|
|
| 25樓: | >>參與討論 |
| 作者: wqi1012 于 2005/2/4 17:20:00 發(fā)布:
有錯! 所以我問你的設計思想到底是什么呢! 按照你原來的寫法,mout只會有效一次,不會形成脈沖。 另外,你信邪的那段程序中又有3個posedge,去掉posedge mget, always @(posedge mclk or posedge rst) begin if(rst) mcount2_stop<=0; else if (!mout) <= mcount2_stop <=0; else if(mget) mcount2_stop <=1; end |
|
| 26樓: | >>參與討論 |
| 作者: chaojijing 于 2005/2/4 17:44:00 發(fā)布:
還是有問題 我這個程序的本意就是一次次發(fā)脈沖,一次次接收,計算每次的時間啊并存入rega中。 不好意思,我本來用3個posedge是想mget能夠異步操作的,因為我現(xiàn)在看的這本書上有這樣的用法,所以我以為可以用的.... 第一次還是沒計數,第二個脈沖就對了,如圖 另外rega的值為什么出現(xiàn)了兩個,而且只一個時鐘周期就置0了,而我希望保持rega到下次值來或是我有其他條件要清0 rega的時候的,源程序中沒有清0rega的語句,為什么它自動清0了呢? * - 本貼最后修改時間:2005-2-4 17:53:13 修改者:chaojijing
|
|
| 27樓: | >>參與討論 |
| 作者: wqi1012 于 2005/2/4 19:00:00 發(fā)布:
回復! 被清零是由于異步reset的緣故。如果想保持,就不能用這種寫法,直接拿mget當時鐘。 always @(posedge mget) rega <= mcount2; |
|
| 28樓: | >>參與討論 |
| 作者: chaojijing 于 2005/2/4 21:39:00 發(fā)布:
好 我明天再去公司試下 至于為什么第一個脈沖還是沒有計數是什么原因有答案嗎? |
|
| 29樓: | >>參與討論 |
| 作者: wqi1012 于 2005/2/5 9:53:00 發(fā)布:
初值 可能是初值的問題吧!我不知道你當時程序是什么樣的,我也只能猜! |
|
| 30樓: | >>參與討論 |
| 作者: chaojijing 于 2005/2/5 9:57:00 發(fā)布:
好,我再想想吧 你的耐心指導令我感動,再次感謝,預祝新年快樂 我把你加入好友了,你不介意吧^O^ |
|
| 31樓: | >>參與討論 |
| 作者: wqi1012 于 2005/2/5 11:10:00 發(fā)布:
回復! 別客氣! 問題解決了就好! 也祝你新年快樂! |
|
|
|
| 免費注冊為維庫電子開發(fā)網會員,參與電子工程師社區(qū)討論,點此進入 |
Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號 |