通用型8bit計數器

  1. 通用型8bit計數器
    1. TopModule
    2. 正數和反數計數器
    3. 第三個部份處理_wrapstop、overflow

通用型8bit計數器

原文連結: https://darkblack01.blogspot.com/2013/05/8bit.html
移植時的最後更新日期: 2013-05-24T15:34:59.813+08:00

介紹一個通用型8bit計數器。


TopModule

可以看見,一個這樣多要求(功能)的計數器,拆成三個部份。
include "InitSel.v"<br />include "Counter8combi.v"
include "CircleStop.v"<br /><br />module counter8uni2(clk, _areset, _aset, _load, preld_val, _updown, _wrapstop, dcout, overflow);<br />parameter countWidth = 8;<br /><br /> input clk,<br /> _areset,<br /> _aset,<br /> _load,<br /> _updown,<br /> _wrapstop;<br /> input [countWidth-1:0] preld_val;<br /><br /> output [countWidth-1:0] dcout;<br /> output overflow;<br /><br /> wire [countWidth-1:0] tCount_M12, tCountM23;<br /><br /> <br /> InitSel M1( .oCountInitValue(tCount_M12), ._iReset(_areset), ._iSet(_aset), ._iLoad(_load), .iPreldVal(preld_val), .iCountValue(dcout) );<br /> Counter8combi M2( .oCount(tCountM23), .iClk(clk), ._iIsAddOut(_updown), .iCount(tCount_M12) );<br /> CircleStop M3( .oCount(dcout), .iClk(clk), .iCount(tCountM23), ._iWrapstop(_wrapstop), .oOverflow(overflow) );<br />endmodule</code></pre><br /><br />下面我們就來詳細的解說,這三個部份怎麼滿足<a href="http://darkblack01.blogspot.com/2013/05/16bit.html">這些規格</a>吧!<br /><br /><h3><span style="font-size: x-large;">第一個部份</span><span style="font-size: x-large;">處理</span><span style="font-size: x-large;">_areset、_aset、_load</span></h3>這個部份要滿足<br /><br /><ul><li>_areset =1 counter非同步輸出全0, _aset =1 counter非同步輸出全1, 若這兩個都是0, count照常運作</li><li>_load = 1時, preld-val的值設定進counte</li><li>訊號優先權_areset &gt; _aset &gt; _load</li></ul><br />最重要的一件事就是「非同步」,這個電路,沒有clk。<br />再來是優先權_areset &gt; _aset &gt; _load,所以code 的排序也是要注意的<br />在此使用always+準位觸發,用Blocking的方式,做非同步電路。<br /><pre class="prettyprint"><code class="language-c">module InitSel(oCountInitValue, _iReset, _iSet, _iLoad, iPreldVal, iCountValue);<br />parameter CountWidth = 8;<br /><br />input _iReset, _iSet, _iLoad;<br />input [CountWidth-1:0] iCountValue, iPreldVal;<br />output [CountWidth-1:0] oCountInitValue;<br /><br />reg [CountWidth-1:0] oCountInitValue;<br /> <br /> always@(_iReset, _iSet, _iLoad, iCountValue, iPreldVal)<br /> begin<br /> if (_iReset == 1)<br /> oCountInitValue = 8'b1111_1111;<br /> else if (_iSet == 1)<br /> oCountInitValue = 8'b0000_0000;<br /> else if (_iLoad == 1)<br /> oCountInitValue = iPreldVal;<br /> else<br /> oCountInitValue = iCountValue;<br /> end<br /> <br />endmodule</code></pre><br /><h3><span style="font-size: x-large;">第二個部份處理_updown</span></h3>這個部份是最重要的計數核心<br />滿足一個規格<br /><ul><li>_updown = 1, counter向上計數 counter = 0, counter向下計數</li></ul>在此設計了兩個電路,正數和反數,獨立著,再使用開關的方式切換輸出和輸入的值。重點在於線路的設計,計數本身反而就是一般的計數,沒什麼特別的。<br /><br /><pre class="prettyprint"><code class="language-c">include “coreCount8Add.v”
`include "coreCount8Sub.v"

module Counter8combi(iClk, _iIsAddOut, iCount, oCount);
parameter CountWidth = 8;

input iClk, _iIsAddOut;
input [CountWidth-1:0] iCount;
output [CountWidth-1:0] oCount;

wire [CountWidth-1:0] out_Add, out_Sub;

assign oCount = (_iIsAddOut)? out_Add: out_Sub;

coreCount8Add CA(iClk, _iIsAddOut, iCount, out_Add);
coreCount8Sub CS(iClk, _iIsAddOut, iCount, out_Sub);

endmodule

正數和反數計數器

它們差異不大,在此貼出反數的code,正數就改一下就是了
正數修改處

  • _iEn改iEn
  • 運算符號-改+

module coreCount8Sub(iClk, _iEn, iCount, oCount);
parameter CountWidth = 8;

input iClk, _iEn;
input [CountWidth-1:0] iCount;
output [CountWidth-1:0] oCount;

reg [CountWidth-1:0] oCount;

always@(posedge iClk)
begin
if (!_iEn)
oCount <= iCount - 8’d1;
else
oCount <= iCount;
end

endmodule


第三個部份處理_wrapstop、overflow

在此也可以使用state mechine,但是我沒這麼做!
規格如下
  • _wrapstop = 1, counter循環計數, _wrapstop = 1, counter計數到最大或最小就停止,並且有overflow
  • 承上,若計數超出範圍(超過最大值或低於最小值)則overflow = 1
module CircleStop(oCount, iClk, iCount, _iWrapstop, oOverflow);
parameter countWidth = 8;

input _iWrapstop, iClk;
input [countWidth-1:0] iCount;
output oOverflow;
output [countWidth-1:0] oCount;

reg [countWidth-1:0] oCount;
reg oOverflow;

always@(posedge iClk)
begin
if ((_iWrapstop == 1) && ((oCount == 8’b0000_0000)))
begin
oCount <= 8’b0000_0000;
oOverflow <= 'b1;
end
else if ((_iWrapstop == 1) && (oCount == 8’b1111_1111))
begin
oCount <= 8’b1111_1111;
oOverflow <= 'b1;
end
else
begin
oCount <= iCount;
oOverflow <= 'b0;
end
end

endmodule

這樣就組成了一個8bit的通用計數器。