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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

HDLBits答案(18)_Verilog有限状态机(5)

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

Verilog有限狀態機(5)

HDLBits鏈接


前言

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


題庫

題目描述1:

第一道題目比較容易,題目中的in信號包含了一個起始位(0),8個數據位和一個停止位(1),開始in為1,也就是IDLE狀態,當in為0時,進入START狀態,然后經過8個周期,如果in為1,則進入STOP狀態,接著如果in為0,進入第二輪START狀態,否則進入IDLE狀態。

這里我用了很多個狀態,實際上可以用計數器來代替中間的8個狀態,這里是8個周期,如果是100個、200個周期,那么需要100個、200個狀態,顯然不現實。這道題目是三道題目中的基礎題,大家不用考慮那么多,直接完成就好了。

Solution1:

module top_module(input clk,input in,input reset, // Synchronous resetoutput done ); parameter [3:0] START = 4'd0;parameter [3:0] ONE = 4'd1;parameter [3:0] TWO = 4'd2;parameter [3:0] THREE = 4'd3;parameter [3:0] FOUR = 4'd4;parameter [3:0] FIVE = 4'd5;parameter [3:0] SIX = 4'd6;parameter [3:0] SEVEN = 4'd7;parameter [3:0] EIGHT = 4'd8;parameter [3:0] STOP = 4'd9;parameter [3:0] IDLE = 4'd10;parameter [3:0] WAIT = 4'd11;reg [3:0] state,next_state;always @(*)begincase(state)START:beginnext_state <= ONE;endONE:beginnext_state <= TWO;endTWO:beginnext_state <= THREE;endTHREE:beginnext_state <= FOUR;endFOUR:beginnext_state <= FIVE;endFIVE:beginnext_state <= SIX;endSIX:beginnext_state <= SEVEN;endSEVEN:beginnext_state <= EIGHT;endEIGHT:beginif(in)beginnext_state <= STOP;endelse beginnext_state <= WAIT;endendSTOP:beginif(in)beginnext_state <= IDLE;endelse beginnext_state <= START;endendWAIT:beginif(in)beginnext_state <= IDLE;endelse beginnext_state <= WAIT;endendIDLE:beginif(~in)beginnext_state <= START;endelse beginnext_state <= IDLE;endendendcaseendalways @(posedge clk)beginif(reset)beginstate <= IDLE;endelse beginstate <= next_state;endendassign done = (state == STOP);endmodule

題目描述2:

這道題目是上一道題目的擴展,不僅需要輸出done信號,還需要輸出數據。

Solution2:

/* way 1*/ module top_module(input clk,input in,input reset, // Synchronous resetoutput [7:0] out_byte,output done ); //parameter [3:0] START = 4'd0;parameter [3:0] ONE = 4'd1;parameter [3:0] TWO = 4'd2;parameter [3:0] THREE = 4'd3;parameter [3:0] FOUR = 4'd4;parameter [3:0] FIVE = 4'd5;parameter [3:0] SIX = 4'd6;parameter [3:0] SEVEN = 4'd7;parameter [3:0] EIGHT = 4'd8;parameter [3:0] STOP = 4'd9;parameter [3:0] IDLE = 4'd10;parameter [3:0] WAIT = 4'd11;reg [3:0] state,next_state;reg [7:0] par_in;always @(*)begincase(state)START:beginnext_state <= ONE;par_in[0] <= in;endONE:beginnext_state <= TWO;par_in[1] <= in;endTWO:beginnext_state <= THREE;par_in[2] <= in;endTHREE:beginnext_state <= FOUR;par_in[3] <= in;endFOUR:beginnext_state <= FIVE;par_in[4] <= in;endFIVE:beginnext_state <= SIX;par_in[5] <= in;endSIX:beginnext_state <= SEVEN;par_in[6] <= in;endSEVEN:beginnext_state <= EIGHT;par_in[7] <= in;endEIGHT:beginif(in)beginnext_state <= STOP;endelse beginnext_state <= WAIT;endendSTOP:beginif(in)beginnext_state <= IDLE;endelse beginnext_state <= START;endendWAIT:beginif(in)beginnext_state <= IDLE;endelse beginnext_state <= WAIT;endendIDLE:beginif(~in)beginnext_state <= START;endelse beginnext_state <= IDLE;endendendcaseendalways @(posedge clk)beginif(reset)beginstate <= IDLE;endelse beginstate <= next_state;endendassign done = (state == STOP);assign out_byte = (state == STOP) ? par_in : 8'd0;endmodule/* way 2 */ module top_module(input clk,input in,input reset, // Synchronous resetoutput [7:0] out_byte,output done ); parameter IDLE = 3'd0, START = 3'd1, DATA = 3'd2;parameter STOP = 3'd3, WAIT = 3'd4;reg [3:0] current_state;reg [3:0] next_state;reg [3:0] counter;reg [7:0] par_in;// Use FSM from Fsm_serialalways @(*)begincase(current_state)IDLE:beginif(~in)beginnext_state = START;endelse beginnext_state = IDLE;endendSTART:beginnext_state = DATA;endDATA:beginif(counter == 4'd8)beginnext_state = in? STOP:WAIT;endelse beginnext_state = DATA;endendSTOP:beginnext_state = in? IDLE:START;endWAIT:beginnext_state = in? IDLE:WAIT;enddefault:beginnext_state = IDLE;endendcaseendalways @(posedge clk)beginif(reset)begincurrent_state <= IDLE;endelse begincurrent_state <= next_state;endendalways @(posedge clk)beginif(reset)begindone <= 1'd0;out_byte <= 8'd0;counter <= 4'd0;endelse begincase(next_state)IDLE:begindone <= 1'd0;out_byte <= 8'd0;counter <= 4'd0;endSTART:begindone <= 1'd0;out_byte <= 8'd0;counter <= 4'd0;endDATA:begindone <= 1'd0;out_byte <= 8'd0;par_in[counter] <= in;counter <= counter + 1'd1;endSTOP:begindone <= 1'd1;out_byte <= par_in;counter <= 4'd0;endWAIT:begindone <= 1'd0;out_byte <= 8'd0;counter <= 4'd0;endendcaseendend// New: Datapath to latch input bits.endmodule

上述第一種解法雖然正確,但是會生成鎖存器,并且這里只有1個字節數據還好,用8個狀態是可以的,如果換成了10個字節、100個字節,難道要80、800個狀態嗎?這是不可能的,于是便誕生了方法二博主最想讓大家使用的方法。大家可以好好看一下,這里將8個數據狀態定義成了一個DATA狀態,不用定義S1、S2、S3什么的了,在狀態機的第三段,將除了DATA狀態的其他狀態時的counter都清零,只有到了DATA狀態時開始計數,順便將par_in中的位數用counter代替,這樣只需要增加counter和out_byte的位寬,就可以實現任意寬度數據的輸出,實用性強。

題目描述3:

較上題添加了奇偶校驗位。

module top_module(input clk,input in,input reset, // Synchronous resetoutput [7:0] out_byte,output done ); //parameter IDLE = 3'd0,START = 3'd1,DATA = 3'd2;parameter STOP = 3'd3,WAIT = 3'd4;reg [2:0] current_state,next_state;reg [3:0] counter;reg [8:0] data_in;reg odd_temp;wire Isdone;// Modify FSM and datapath from Fsm_serialdataalways @(*) begincase(current_state)IDLE:beginif(~in)beginnext_state = START;endelse beginnext_state = IDLE;endendSTART:beginnext_state = DATA;endDATA:beginif(counter == 4'd9)beginnext_state = in ? STOP : WAIT;endelse beginnext_state = DATA;endendSTOP:beginnext_state = in ? IDLE : START;endWAIT:beginnext_state = in ? IDLE : WAIT;enddefault:beginnext_state = IDLE;endendcaseendalways @(posedge clk) beginif(reset)begincurrent_state <= IDLE;endelse begincurrent_state <= next_state;endendalways @(posedge clk) beginif(reset)begindone <= 1'd0;out_byte <= 8'd0;counter <= 4'd0;endelse begincase(next_state)IDLE:begindone <= 1'd0;out_byte <= 8'd0;counter <= 4'd0;endSTART:begindone <= 1'd0;out_byte <= 8'd0;counter <= 4'd0;endDATA:begindone <= 1'd0;out_byte <= 8'd0;counter <= counter + 1'd1;data_in[counter] <= in;endSTOP:begindone <= odd_temp ? 1'd1 : 1'd0;out_byte <= odd_temp ? data_in[7:0] : 8'd0;counter <= 4'd0;endWAIT:begindone <= 1'd0;out_byte <= 8'd0;counter <= 4'd0;endendcaseendend// New: Add parity checking.assign Isdone = (next_state == START);parity u0(clk,Isdone,in,odd_temp);endmodule

該題答案與上題類似,這里我將奇偶校驗位數據也計算在DATA狀態內,判斷起來相對較容易,大家可以借鑒一下。

注意作者在題目中給了奇偶校驗的模塊,大家直接調用即可。

結語

好久沒更新HDLBits了,寒假在家閑來無事,希望勉勵自己把HDLBits刷完吧,加油!有問題的地方歡迎大家與我討論交流。

總結

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

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