日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HDLBits答案(19)_Verilog有限状态机(6)

發布時間:2023/12/19 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDLBits答案(19)_Verilog有限状态机(6) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Verilog有限狀態機(6)

HDLBits鏈接


前言

今天繼續更新狀態機小節的習題。


題庫

Fsm hdlc

同步幀檢測涉及對數據的連續位流進行解碼,以尋找指示幀(數據包)開始和結束的位模式。 6個連續的1(即01111110)是表示幀邊界的“標志”。 為了避免數據流意外包含“標志”,發送方必須在接收方必須檢測并丟棄的每5個連續的1秒后插入一個零。 如果連續7個或更多1,我們還需要發出錯誤信號。

可以通過狀態機來識別下面三種序列:

0111110:表示5個1后面的0bit需被忽略;

01111110:表示一幀的開始或結束;

01111111…:錯誤

當狀態機被復位時,它應當表現為之前的輸入為0;

下面是三種波形示例:

官方提供的狀態機設計提示:

Solution:

//----------------way1---------------------- module top_module(input clk,input reset, // Synchronous resetinput in,output disc,output flag,output err);parameter NONE = 4'd0,ONE = 4'd1,TWO = 4'd2;parameter THREE = 4'd3,FOUR = 4'd4,FIVE = 4'd5;parameter SIX = 4'd6,ERROR = 4'd7;parameter DISC = 4'd8,FLAG = 4'd9;reg [3:0] current_state,next_state;always @(*) begincase(current_state)NONE:beginnext_state = in ? ONE : NONE;endONE:beginnext_state = in ? TWO : NONE;endTWO:beginnext_state = in ? THREE : NONE;endTHREE:beginnext_state = in ? FOUR : NONE;endFOUR:beginnext_state = in ? FIVE : NONE;endFIVE:beginnext_state = in ? SIX : DISC;endSIX:beginnext_state = in ? ERROR : FLAG;endDISC:beginnext_state = in ? ONE : NONE;endFLAG:beginnext_state = in ? ONE : NONE;endERROR:beginnext_state = in ? ERROR : NONE;endendcaseendalways @(posedge clk) beginif(reset)begincurrent_state <= NONE;endelse begincurrent_state <= next_state;endendalways @(posedge clk) beginif(reset)begindisc <= 1'd0;flag <= 1'd0;err <= 1'd0;endelse begincase(next_state)DISC:begindisc <= 1'd1;flag <= 1'd0;err <= 1'd0;endFLAG:begindisc <= 1'd0;flag <= 1'd1;err <= 1'd0;endERROR:begindisc <= 1'd0;flag <= 1'd0;err <= 1'd1;enddefault:begindisc <= 1'd0;flag <= 1'd0;err <= 1'd0;endendcaseendendendmodule //----------------way2---------------------- module top_module(input clk,input reset, // Synchronous resetinput in,output disc,output flag,output err);parameter NONE = 3'd0,DATA = 3'd1;parameter DISC = 3'd2,FLAG = 3'd3,ERROR = 3'd4;reg [2:0] current_state,next_state;reg [2:0] counter;always @(*) begincase(current_state)NONE:beginnext_state = in ? DATA : NONE;endDATA:begincase(counter)3'd5: next_state = in ? DATA : DISC;3'd6: next_state = in ? ERROR : FLAG;default:next_state = in ? DATA : NONE;endcaseendDISC:beginnext_state = in ? DATA : NONE;endFLAG:beginnext_state = in ? DATA : NONE;endERROR:beginnext_state = in ? ERROR : NONE;endendcaseendalways @(posedge clk) beginif(reset)begincurrent_state <= NONE;endelse begincurrent_state <= next_state;endendalways @(posedge clk) beginif(reset)begindisc <= 1'd0;flag <= 1'd0;err <= 1'd0;counter <= 3'd0;endelse begincase(next_state)DATA:begindisc <= 1'd0;flag <= 1'd0;err <= 1'd0;counter <= counter + 1'd1;endDISC:begindisc <= 1'd1;flag <= 1'd0;err <= 1'd0;counter <= 3'd0;endFLAG:begindisc <= 1'd0;flag <= 1'd1;err <= 1'd0;counter <= 3'd0;endERROR:begindisc <= 1'd0;flag <= 1'd0;err <= 1'd1;counter <= 3'd0;enddefault:begindisc <= 1'd0;flag <= 1'd0;err <= 1'd0;counter <= 3'd0;endendcaseendendendmodule

其中way1與題目提示的思路相同,其中第三段狀態機一開始忘記加reset的那種情況,果然還是長時間沒接觸verilog手生了,以后繼續練習;

way2使用counter去掉中間狀態,靠輸入和counter的值來決定狀態轉移,是一種米利狀態機的思想;狀態轉移圖如下(手繪有點丑,見諒):

米利型狀態機

檢測輸入的X中”101“是否出現,出現的話輸出Z為1,否則為0。復位為異步低電平復位;只允許出現3種狀態;允許交疊檢測:即輸入若為10101時,Z應該在時刻3和時刻5各輸出一次1;

代碼中主要妙在兩處:一是如何用3種狀態表示,需在第三種狀態中將輸出與輸入關聯起來;二是如何進行交疊檢測,狀態的轉移有妙處;

Solution

module top_module (input clk,input aresetn, // Asynchronous active-low resetinput x,output z ); parameter S0 = 2'd0,S1 = 2'd1,S2 = 2'd2;reg [1:0] current_state,next_state;always @(*) begincase(current_state)S0: next_state = x ? S1 : S0;S1: next_state = x ? S1 : S2;S2: next_state = x ? S1 : S0;endcaseendalways @(posedge clk or negedge aresetn) beginif(~aresetn)begincurrent_state <= S0;endelse begincurrent_state <= next_state;endendalways @(*) beginz = (current_state == S2) ? x : 1'b0;endendmodule

Q5a:Serial two’s complementer(Moore FSM)

作者這里假設我們這邊輸入的都是負數,不用管符號位的問題;即補碼全部都是取反加1求得。

以上圖為例,輸入的左邊為低位數據,右邊為高位數據;即輸入為00110100,則取反加1后得輸出為11001100;

取反操作好進行,主要麻煩在加一的操作上,不知道進位到哪一位為止,此時我們用狀態機來解決;若最前面的輸入都是0的話,取反均為1,低位加1的時候一直進位,則輸出都是0,直到輸入有個1為止(取反加1不進位),這一階段我們用一個狀態S0來表示;后面階段就將輸入取反進行輸出即可,因為進位鏈在S0狀態已結束;

因為是摩爾型狀態機,狀態的轉移與輸入無關,所以我們這里用到3個狀態,代碼如下所示:

Solution

module top_module (input clk,input areset,input x,output z ); parameter S0 = 2'd0, S1 = 2'd1, S2 = 2'd2;reg [1:0] current_state, next_state;always @(*) begincase(current_state)S0: next_state = x ? S1 : S0;S1: next_state = x ? S2 : S1;S2: next_state = x ? S2 : S1;endcaseendalways @(posedge clk or posedge areset) beginif(areset)begincurrent_state <= S0;endelse begincurrent_state <= next_state;endendassign z = (current_state == S1);endmodule

Q5b:Serial two’s complementer(Mealy FSM)

題意與上題相同,此時用米利型狀態機實現。下面是官方提供的狀態轉移提示:

module top_module (input clk,input areset,input x,output z ); parameter S0 = 1'b0, S1 = 1'b1;reg current_state,next_state;always @(*) begincase(current_state)S0: next_state = x ? S1 : S0;S1: next_state = S1;endcaseendalways @(posedge clk or posedge areset) beginif(areset)begincurrent_state <= S0;endelse begincurrent_state <= next_state;endendassign z = ((current_state == S0) && x) || ((current_state == S1) && ~x);endmodule

結語

今天先更新這幾題吧,大家如果對轉補碼的題目還有什么疑問歡迎評論交流,代碼有不足之處還望指正。

總結

以上是生活随笔為你收集整理的HDLBits答案(19)_Verilog有限状态机(6)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。