2021年4月10日 星期六

使用Quartus-II 9.1SP2 + ModelSim 6.5b-Aletra + Altera DE2-115 FPGA開發平台,設計 位元串流 (bit stream) 中出現 "101" 時輸出 high FSM 為例(FPGA開發平台)

使用Quartus-II 9.1SP2 + ModelSim 6.5b-Aletra + Altera DE2-115 FPGA開發平台,設計  FSM 為例(FPGA開發平台)

設計一個信號偵測器, 當位元串流 (bit stream) 中出現 "101" 時輸出 high, 否則輸出 low


參考來源http://yhhuang1966.blogspot.com/2019/06/finite-state-machine.html

範例  : Moore 信號偵測器

設計一個信號偵測器, 當位元串流 (bit stream) 中出現 "101" 時輸出 high, 否則輸出 low. 例如 :

首先以 Moore 機來設計, 依據設計要求描述, 因為要偵測的信號標記是 3 個位元, 若使用 Moore 機來設計的話需要四個狀態來記錄已收到之信號, 這是一個逐步接近目標狀態 "101" 之進程 :

S0 : 0 received, output 0 
S1 : 1 received, output 0 
S2 : 10 received, output 0
S3 : 101 received, output 1

狀態圖如下 :

注意, 只有進入 S3 狀態 (已收到 "101") 才會輸出 1, 否則都輸出 0. 其次, 在 S3 收到 0 是進入 S2, 不是 S0, 因為在 S3 已收到 101, 若在收到 0 表示已收到 1010, 後兩位元是 10, 此為 S2 狀態.

狀態圖畫好後需指定狀態值 (即編碼), 四個狀態需要兩個位元編碼, 因為 2**2=4. 編碼可任意指定, 此處指定 S0=00, S1=01, S2=10, S3=11. 然後將狀態圖填入狀態表中 :

填表的方法是先將最左邊 S0~S3 的現態值填好, 然後依據狀態圖由上而下逐列填寫次態與輸出 :

  1. 在 S0 狀態時輸出 0, 收到 0 次態為 S0, 收到 1 次態為 S1. 
  2. 在 S1 狀態時輸出 0, 收到 0 次態為 S2, 收到 1 次態為 S1. 
  3. 在 S2 狀態時輸出 0, 收到 0 次態為 S0, 收到 1 次態為 S3. 
  4. 在 S3 狀態時輸出 1, 收到 0 次態為 S2, 收到 1 次態為 S1. 

接著要結合狀態表與正反器為一張轉態表, 以下將使用 D 與 JK 正反器, 其激勵表如下 :

轉態表實際上就是狀態表的延伸, 它將輸入與現態做排列組合, 並多出一個正反器輸入欄位, 依據激勵表填入每一個現態變成次態所需之輸入條件.


例如 JK 正反器的轉態表中, 第一列 Q0 狀態由 0 變 0, 從激勵表可知所需知輸入為 J0=0, K0=X. 第四列 Q1 由 1 變 0, 從激勵表可知所需知輸入為 J0=X, K0=1. 如此這般由上而下依序將第四欄的 JK excitation 填好, 輸出部分因 Moore 機輸出只與現態有關, 因此只在現態 Q0Q1=11 時輸出 1 :

如果用 D 正反器來做, 則轉態表就更容易填寫了, 因為正反器的輸入 D0D1 不用像 JK 那樣要去查看激勵表 (當然, 若背得起來的話是不用查), 直接將次態 (next state) 複製過來就行了 (凡事皆有代價, 這麼方便的代價是電路可能較複雜, 需要較多邏輯閘來實現) :

轉態表填好後就可以用卡諾圖求取正反器的輸入方程式了, 卡諾圖的變數有三個, 一個是輸入 X, 另外是正反器的現態 Q0 與 Q1 一組. 注意, 卡諾圖相鄰只能有一個變化, 因此 Q0Q1 排列依序是 00-01-11-10.


以 J0 為例, 只有在 XQ0Q1=001 (注意這裡 Q0Q1 是指現態) 時 J0 才為 1, XQ0Q1=000, 100, 與 101 時為 0, 其餘的組合均為 X (don't care), 填入卡諾圖後發現 XQ0Q1=001 可與 011 的 X 結合 (因 X 表示可以為 0 也可以為 1, 把它當作 1 比較有利), 這個組合項 X 部分為 0, Q0Q1 部分 Q0 消失只剩 Q1, 因此 J0=/XQ1, 其餘各方程式依此方法求得, 結果如下圖所示 :


如果以 D 正反器來實現, 則其卡諾圖化簡如下圖所示 :


因為 Moore 機輸出只與正反器狀態有關, 與輸入沒有直接相關, 因此不論是用 JK 還是 D, 其輸出都是 Y=Q0Q1 :


輸入方程式求出來後就可以繪製電路圖 :


這樣就完成整個設計.

module DE2_115 (SW, LEDR, LEDG , CLOCK_50 ,KEY ,HEX0 ,HEX1 ,HEX2,HEX3,HEX4 ,HEX5 ,HEX6,HEX7, GPIO );
 input  [17:0] SW;   // toggle switches
 input  [7:0] KEY;       // Push bottom
 input  CLOCK_50;   //Clock 27MHz , 50Mhz
 output [17:0] LEDR;   // red  LEDS
 output [8:0] LEDG;   // green LEDs
 output [6:0] HEX0,HEX1,HEX2,HEX3; //7-segment display
 output [6:0] HEX4,HEX5,HEX6,HEX7; //7-segment display
 inout  [35:0] GPIO;
 //assign HEX0=7'b111_1111;
 assign HEX1=7'b111_1111;
 assign HEX2=7'b111_1111;
 assign HEX3=7'b111_1111;
 assign HEX4=7'b111_1111;
 assign HEX5=7'b111_1111;
 assign HEX6=7'b111_1111;
 assign HEX7=7'b111_1111;
 
 wire [7:0] segout0;   //HEX 0
 wire c , serout ;
 wire [3:0]countout;
 
 //module Clock_1Hz(clk, reset, clk_1Hz);
 //input clk, reset;
 //output clk_1Hz;
 Clock_1Hz(CLOCK_50,SW[17],clk1);
 assign LEDG[1]=clk1;
 assign LEDR=SW;
 
 
 counter_4bit (clk1,SW[17],countout);
  _7seg UUT0(.hex(countout), .seg(segout0));
  assign HEX0=segout0[6:0];

 //module shift16bit (Clk, ALOAD,D, SO); 
 //input  Clk,ALOAD; 
 //input [15:0] D; 
 //output SO; 

 shift16bit (clk1,SW[17],SW[15:0],serout);

 FSM_detect_101(serout,clk1,LEDG[0]);
 
 
endmodule
//============================================================

module counter_4bit (
  input clk,      
  // Declare input port for the clock to allow counter to count up  
  input rstn,              
  // Declare input port for the reset to allow the counter to be reset to 0 when required  
  output reg[3:0] out);    
  // Declare 4-bit output port to get the counter values  
  
  // This always block will be triggered at the rising edge of clk (0->1)  
  // Once inside this block, it checks if the reset is 0, then change out to zero   
  // If reset is 1, then the design should be allowed to count up, so increment the counter   
  
  always @ (posedge clk) begin  
    if (!rstn)  
      out <= 0;  
    else  
      out <= out + 1;  
  end  
endmodule  
//============================================================
module FSM_detect_101(Xin,CLK,Y);
input Xin,CLK;
output Y;
wire j0,k0,j1,k1,q1,q0;
assign j1= Xin;
assign k1= ~Xin;
assign j0= q1 &k1;
assign k0 = ~(q1 ^Xin);

JK_FF U1 (j1,k1,CLK,q1);
JK_FF U0 (j0,k0,CLK,q0);
        assign Y=(q0 & q1) ;   
endmodule
//============================================================
//JK 正反器(Flip-Flop)
module JK_FF(J,K,CLK,Q);
       output Q;
       input J,K,CLK;
       reg Q;
 
       always @ (posedge CLK)
       case ({J,K})
              2'b00: Q = Q;
              2'b01: Q = 1'b0;
              2'b10: Q = 1'b1;
              2'b11: Q = ~ Q;
       endcase
endmodule
//============================================================
//1 HZ CLOCK GENERATOR
module Clock_1Hz(clk, reset, clk_1Hz);
input clk, reset;
output clk_1Hz;
reg clk_1Hz = 1'b0;
reg [27:0] counter;
always@(negedge reset or posedge clk)
begin
    if (!reset)
        begin
            clk_1Hz <= 0;
            counter <= 0;
        end
    else
        begin
            counter <= counter + 1;
            if ( counter == 25_000_000)
                begin
                    counter <= 0;
                    clk_1Hz <= ~clk_1Hz;
                end
        end
end
endmodule  
//============================================================
//8-bit Shift-Left Register with Positive-Edge Clock, 
//Asynchronous Parallel Load, Serial In, and Serial Out
module shift16bit (Clk, ALOAD,D, SO); 
input  Clk,ALOAD; 
input [15:0] D; 
output SO; 
reg [15:0] tmp; 
 
  always @(posedge Clk or negedge ALOAD) 
  begin 
    if (!ALOAD) 
      tmp = D; 
    else 
      begin 
        tmp = {tmp[14:0],tmp[15]}; 
      end 
  end 
  assign SO  = tmp[15]; 
endmodule 

//============================================================


沒有留言:

張貼留言

作業3 替代方案 WOKWI + Node-Red 免安裝版 RFID 是利用亂數產生器 模擬的UID卡號

作業3 替代方案 WOKWI + Node-Red 免安裝版  RFID 是利用亂數產生器 模擬的UID卡號 方塊圖 RFID 是利用亂數產生器 模擬的UID卡號 Node-Red 免安裝版本 下載點2處 --> 選1 下載 https://sourceforge.net/...