三要素 初值 加1條件 結束值
三要素確定乙個計數器,逐一考慮。eg,下圖新增on訊號,作為加一條件 on訊號也是單週期訊號的延展訊號
初值為0所有計數器從0開始計數,便於閱讀(減少**的閱讀量)就不用閱讀計數器的定義部分啦,可以快速看出計數了多少次
結束值為0使得計數器迴圈重複使用計數器記完就清零 在最後乙個加一條件的時候清零。end_cnt 也是在說最後乙個加一條件
數值意義cnt = x - 1 加一條件有效的時候,數到了x下
取值格式
根據計數器產生訊號的時候, 要數x下然後變化(拉高)
assign dout = (add_cnt)&&(cnt==x-1);
結束條件
同時滿足加一條件,結束值時x-1的格式;
(無論多麼經驗豐富的工程師,對於邊界條件總要花心思來考慮)
取值範圍
範圍限定 邊界問題考慮 使用》= < 兩種符號。
range(0,8)
for(i=0;i<8;i++)
比如取前7個數 cnt>=0 && cnt<7;
從10開始 數16個 cnt>=10 && cnt<10+16;
計數框架
向框架對齊
向計數器直接對其 防止一環扣一環
先建立框架 再加其他訊號
always @(posedge clk)begin
if(!rst_n)begin
cnt0 <= 0;
endelse if(add_cnt0)begin // 加一條件滿足的時候 先判斷是否是結束 再加一
if(end_cnt0)
cnt0 <= 0;
else
cnt0 <= cnt0 + 1;
endend
//!------計數器0----0️⃣--------------
assign add_cnt0 = (dout);
assign end_cnt0 = add_cnt0&&(cnt0== 3-1 );
這一階段訓練的大都是en訊號之後,輸出一定規律的脈衝。如en訊號之後隔3個週期,輸出4個週期的高電平;隔3個週期,輸出1個,2個,3個,4個,週期高電平等等。
使用乙個或者兩個計數器來計數即可。這裡要有乙個en訊號之後表示的加一訊號(我理解為en脈衝的延拓)來持續刺激計數器的加一操作,同時這個延拓訊號的結束通常由計數器的值來進行判斷。
在en訊號脈衝之後 產生10個高電平輸出計數器+1條件使用輸出訊號表示,輸出訊號的拉低條件使用計數器的結束條件表示。這裡的加一訊號與輸出訊號是乙個訊號。
en之後間隔10個週期 高乙個週期這個情況就不能使用輸出訊號表示加一訊號了,flag數11個週期 更方便.
abxn模組
在練習中有很多 en訊號之後隔a個週期,有乙個b週期的高訊號,這個模式重複n次,這裡在至簡設計法的基礎上寫出了乙個實現這樣功能的模組,避免了**的重複。
//? *********************注釋開始*********************
//? 這個模組使用雙計數器 實現en訊號之後,隔a個週期,產生b個週期的高電平,這個模式重複n次
//? *********************注釋結束*********************
module a_bxn #(parameter abn_w = 4)(
input clk ,
input rst_n ,
//其他輸入訊號
input en,
input [abn_w-1:0] a,b,n,
//輸出訊號
output reg dout,
output reg [abn_w-1:0] cnt1
);//中間訊號定義
reg add_flag0;
reg [abn_w-1:0] cnt0;
wire add_cnt0,end_cnt0;
always @(posedge clk)begin
if(!rst_n)begin
cnt0 <= 0;
endelse if(add_cnt0)begin
if(end_cnt0)
cnt0 <= 0;
else
cnt0 <= cnt0 + 1;
endend
//!------計數器0----0️⃣--------------
assign add_cnt0 = (add_flag0);
assign end_cnt0 = add_cnt0&&(cnt0== a+b-1 );
wire add_cnt1,end_cnt1;
always @(posedge clk)begin
if(!rst_n)begin
cnt1 <= 0;
endelse if(add_cnt1)begin
if(end_cnt1)
cnt1 <= 0;
else
cnt1 <= cnt1 + 1;
endend
//!------計數器1-----1️⃣------------
assign add_cnt1 = (end_cnt0);
assign end_cnt1 = add_cnt1&&(cnt1== n-1 );
always @(posedge clk)begin
if(rst_n==1'b0)begin
add_flag0 <= 0;
endelse begin
if(en) add_flag0 <= 1;
else if(end_cnt1) add_flag0 <= 0;
endendalways @(posedge clk)begin
if(rst_n==1'b0)begin
dout <= 0;
endelse begin
if(add_cnt0 && cnt0==a-1) dout <= 1;
else if(end_cnt0) dout <= 0;
endendendmodule
有些時候,上述ab的值隨著這個模式重複的次序,發生變化,因此該模組還進行輸出了計數器1的計數值,可以在呼叫該模組時進行控制。這裡為了在cnt1變化後ab立即響應,使用組合邏輯來進行ab的賦值。組合邏輯的if else 要全面 (else x=x; 這樣也不行,要有確定的值)
always @(*)begin
if(abxn_cnt1==0)
a = 4;
else if(abxn_cnt1==1)
a = 1;
else if(abxn_cnt1==2)
a = 6;
else
a = 2;
end
en訊號之後,輸出dout為2,持續5個週期,變為零這個同階段一原理一樣,就是把脈衝換成了值。直接採用dout==2作為計數器加一條件,或者新增flag訊號,用於加一。dout訊號根據flag採用組合邏輯,或者根據cnt採用時序邏輯來產生。
計數器設計
最近看到一篇文章說要實現乙個計數器的功能,於是通過思索,設計了乙個靈活可用性高的物件計數器。裡面閃爍著 很多的火花。template class object counter object counter private static int m count template int object ...
計數器設計實驗
module cnt10 clk,rst,en,load,cout,dout,data input clk,en,rst,load input 3 0 data output 3 0 dout output cout reg 3 0 q1 reg cout assign dout q1 always...
Mysql計數器表設計
mysql create table hit counter cnt int unsigned not null engine innodb mysql update hit counter set cnt cnt 1 問題在於,對於任何想要更新這一行的事務來說,這條記錄上都有乙個全域性的互斥鎖 m...