记录一次CPLD资源过少、时序伪例的解决办法
文章目錄
- 1、背景:
- 2、代碼
- 3、心得
1、背景:
CPLD雖然是幾乎淘汰產品,但是體積非常小,而且不需要額外的EPCS存儲器,所以完成簡單的時序來說,也有尚存的一席之地。
這次使用的是MAX V系列的CPLD,完成外部觸發后,產生一個可控低電平,接著是可控高電平的pulse_out1,接著pulse_out2又受pulse_out1的上升沿觸發,接著pulse_out3又受pulse_out2的觸發,以此完成類似的可控操作。
上圖,我已經在我的quartus 13.1中安裝了MAX V系列的CPLD,安裝過程類似于曾經寫的一篇文章:https://blog.csdn.net/ciscomonkey/article/details/87896715
2、代碼
代碼如下:
頂層模塊:
實現了三個pulse的觸發,和上升沿的檢測
底層模塊:
module pulse_out_module # ( parameter low_leval_time=0,//觸發后延遲時間parameter high_leval_time=0, //高電平時間parameter data_width=0 //高電平計數器寬度 ) ( input start, //輸入啟動信號 input sys_clk, input rst, //低電平復位 output pulse_out);localparam IDLE_state=2'b0; localparam low_level_state=2'b01; localparam high_level_state=2'b10;reg pulse_out_reg=0;reg [1:0] now_state=0; reg [1:0] next_state=0;reg [data_width-1:0] leval_cnt; reg start_high_flag=1'b0; reg start_idle_flag=1'b0;//1、實現狀態轉換 always @ (posedge sys_clk or negedge rst) beginif(!rst) //低電平復位now_state<=IDLE_state;elsenow_state<=next_state; end//2、根據條件產生下一個狀態 always@(*) begincase (now_state)IDLE_state:beginif(start)next_state=low_level_state; elsenext_state=IDLE_state;endlow_level_state:beginif(start_high_flag)next_state=high_level_state; elsenext_state=low_level_state;endhigh_level_state:beginif(start_idle_flag)next_state=IDLE_state; elsenext_state=high_level_state;enddefault:next_state=IDLE_state;endcaseend //3、狀態條件輸出 always @ (posedge sys_clk) begin case (next_state)IDLE_state:beginleval_cnt<=0;//high_leval_cnt<=0;endlow_level_state:beginleval_cnt<=leval_cnt+1;endhigh_level_state:beginleval_cnt<=leval_cnt+1;enddefault:;endcaseendalways @ (posedge sys_clk or negedge rst) beginif(!rst)pulse_out_reg<=0;else if(now_state==high_level_state)pulse_out_reg<=1;elsepulse_out_reg<=0; endalways @ (posedge sys_clk) begin if(leval_cnt==low_leval_time-1|low_leval_time==0) start_high_flag<=1; else start_high_flag<=0; endalways @ (posedge sys_clk) begin if(leval_cnt==low_leval_time+high_leval_time-1|low_leval_time==0) start_idle_flag<=1; else start_idle_flag<=0; endassign pulse_out=pulse_out_reg;endmodule時序分析:
以下選擇的是后來我們決定用5M10ZE64C4,時序也是完全符合的,不存在時序違規。
3、心得
1、CPLD體積小,如果僅僅是完成簡單的觸發等時序,完全可以采用CPLD這類器件。
2、CPLD資源相當少,一般邏輯資源如上圖,才160,稍微不注意,就會超標,所以,寄存器輸入一定要盡量減少,位寬需要多少就定義多少,不要定義太寬,可以用assign的,就不用寄存器。能用一個計數器的,絕不用兩個計數器,狀態機位寬、狀態機狀態數目能少盡量少。條件能寫==的,就不寫<=
3、很容易造成時序違規問題,所以,要解決時序違規,可以適當增加一個或兩個寄存器。特別是狀態機里面的條件,可以把條件化為一個寄存器flag標志,滿足條件,輸出flag,從而減小了數據路徑,從而解決時序偽例。在本實際例子中就是這么解決的,從而能讓fmax能跑到如此大。如果忘記了,看看我寫的底層模塊即可。
總結
以上是生活随笔為你收集整理的记录一次CPLD资源过少、时序伪例的解决办法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 雅客EXCEL (3)-合并取消单元格、
- 下一篇: 5.9、离散卷积的一般描述