iT邦幫忙

2022 iThome 鐵人賽

DAY 21
0
Software Development

超簡單的 Verilog 入門講解系列 第 21

[Day 21] Verilog E-1 難度丁 P2海域的消血1 - Rs232訊號協議 等待到Start (設計輸出1 )

  • 分享至 

  • xImage
  •  

[Day 17] 時有講到

那一個訊號有幾個 Clk呢:
(訊號 是 1/115200 秒) / (一個 clk是 1/24M 秒) = 24M/115200 = 208 個 clk

https://ithelp.ithome.com.tw/upload/images/20221004/20135862fG9uWyDkc0.png

因此我們需要一個幫忙計算 是否有達到 288 clk 的reg

reg[7:0] Count_clk;

還有一個就是 計算 幾個 Bin 的紀錄 一樣是 reg

reg[7:0] Count_bin;

只要寫到 reg 記得在 reset 初始他




module Rs232_test1(Data1,clk,reset1,Out1,En_out);
input Data1,reset1 ,clk;
output[7:0] Out1;
output En_out;

reg[7:0] State1;

// 用來計算大小
reg[7:0] Count_clk;
reg[7:0] Count_bin;


always@(negedge reset1 or posedge clk)
begin

if( ~reset1) begin

   Count_clk<=0;
   Count_bin<=0;
   State1 <=0;
end
else begin
    
    case (State1)
    0:
    begin
      
      
    end
    1:
    begin
          
          
    end  
    default:
    begin
          
          
    end
       
    endcase
    
end

end

endmodule 



我們來設計一個計算 1個 Bin大小的方法,一個Bin大小是 288 clk

那就是 Count_clk 數到了 288 就歸零在數一次,並且紀錄第幾個 bin

設計的程式碼如下


if(Count_clk >= 287 ) begin

Count_clk<=0;

end

else begin

Count_clk <= Count_clk + 1;

end

if(Count_clk == 0 )begin
Count_bin <=Count_bin+1;
end


Case 0

https://ithelp.ithome.com.tw/upload/images/20221004/201358624xLG1RMfA7.png

我們設定 Case 0 是 一開始的 High狀態,將剛剛的紀數方法放進 0:



module Rs232_test1(Data1,clk,reset1,Out1,En_out);
input Data1,reset1 ,clk;
output[7:0] Out1;
output En_out;

reg[7:0] State1;

// 用來計算大小
reg[7:0] Count_clk;
reg[7:0] Count_bin;


always@(negedge reset1 or posedge clk)
begin

if( ~reset1) begin

   Count_clk<=0;
   Count_bin<=0;
   State1 <=0;
end
else begin
    
    case (State1)
    0:
    begin
      
        if(Count_clk >= 287 ) begin
        
            Count_clk<=0;
        
        end
        
        else begin
        
            Count_clk <= Count_clk + 1;
        
        end
        
        if(Count_clk == 0 )begin
        
            Count_bin <=Count_bin+1;
            
        end
        
    end
    1:
    begin
          
          
    end  
    default:
    begin
          
          
    end
       
    endcase
    
end

end

endmodule 


一開始的 High狀態有個重點,那就是 他的 Data 輸入都是 High

https://ithelp.ithome.com.tw/upload/images/20221004/20135862W2h9eqVLQR.png

所以需要一個條件,在記錄 Bin 必須是 High


        if(Count_clk == 0 )begin
            if(Data1==1)begin
                Count_bin <= Count_bin+1;
            end
            else begin
                Count_bin <= 0;
            end
        end

放進程式



module Rs232_test1(Data1,clk,reset1,Out1,En_out);
input Data1,reset1 ,clk;
output[7:0] Out1;
output En_out;

reg[7:0] State1;

// 用來計算大小
reg[7:0] Count_clk;
reg[7:0] Count_bin;


always@(negedge reset1 or posedge clk)
begin

if( ~reset1) begin

   Count_clk<=0;
   Count_bin<=0;
   State1 <=0;
end
else begin
    
    case (State1)
    0:
    begin
      
        if(Count_clk >= 287 ) begin
        
            Count_clk<=0;
        
        end
        
        else begin
        
            Count_clk <= Count_clk + 1;
        
        end
        
        if(Count_clk == 0 )begin
            if(Data1==1)begin
                Count_bin <= Count_bin+1;
            end
            else begin
                Count_bin <= 0;
            end
        end
        
    end
    1:
    begin
          
          
    end  
    default:
    begin
          
          
    end
       
    endcase
    
end

end

endmodule 


我們要設定多長呢,那就 15個 bin 之後就 High就當成夠長了

所以數到 15 就跳到下一個狀態


            if(Count_bin== 15 )begin
                State1 <= 1;
            end

放進程式



module Rs232_test1(Data1,clk,reset1,Out1,En_out);
input Data1,reset1 ,clk;
output[7:0] Out1;
output En_out;

reg[7:0] State1;

// 用來計算大小
reg[7:0] Count_clk;
reg[7:0] Count_bin;


always@(negedge reset1 or posedge clk)
begin

if( ~reset1) begin

   Count_clk<=0;
   Count_bin<=0;
   State1 <=0;
end
else begin
    
    case (State1)
    0:
    begin
      
        if(Count_clk >= 287 ) begin
        
            Count_clk<=0;
        
        end
        
        else begin
        
            Count_clk <= Count_clk + 1;
        
        end
        
        if(Count_clk == 0 )begin
            if(Data1==1)begin
                Count_bin <= Count_bin+1;
            end
            else begin
                Count_bin <= 0;
            end
        end
        
        if(Count_bin== 15 )begin
                State1 <= 1;
        end
        
        
    end
    1:
    begin
          
          
    end  
    default:
    begin
          
          
    end
       
    endcase
    
end

end

endmodule 


case 1 : Start

Start 就是 High 轉 Low的瞬間

https://ithelp.ithome.com.tw/upload/images/20221004/20135862KlrGDUBPQZ.png

既然要知道 High 轉 Low的瞬間,我們就要記得上一步的 Data

reg[7:0] Data_Previous1;

有 Reg 就要立刻 初始化



module Rs232_test1(Data1,clk,reset1,Out1,En_out);
input Data1,reset1 ,clk;
output[7:0] Out1;
output En_out;

reg[7:0] State1;


reg[7:0] Count_clk;
reg[7:0] Count_bin;


reg[7:0] Data_Previous1;


always@(negedge reset1 or posedge clk)
begin

if( ~reset1) begin

   Count_clk<=0;
   Count_bin<=0;
   Data_Previous1<=0ㄤ
   State1 <=0;
end
else begin
    
    case (State1)
    0:
    begin
      
        if(Count_clk >= 287 ) begin
        
            Count_clk<=0;
        
        end
        
        else begin
        
            Count_clk <= Count_clk + 1;
        
        end
        
        if(Count_clk == 0 )begin
            if(Data1==1)begin
                Count_bin <= Count_bin+1;
            end
            else begin
                Count_bin <= 0;
            end
        end
        
        if(Count_bin== 15 )begin
                State1 <= 1;
        end
        
        
    end
    1:
    begin
          
          
    end  
    default:
    begin
          
          
    end
       
    endcase
    
end

end

endmodule 


那要怎麼做呢,其實很簡單我們只要指向上一個觸發那瞬間的自己就是 上一個自己


Data_Previous1 <= Data1;

這很難理解我這樣講吧

假設 Data 是隨著 Clk 的下緣才執行,而拿到的是 Clk 上緣

明天有機會再來舉例子

所以我們放在 reset 之後



module Rs232_test1(Data1,clk,reset1,Out1,En_out);
input Data1,reset1 ,clk;
output[7:0] Out1;
output En_out;

reg[7:0] State1;


reg[7:0] Count_clk;
reg[7:0] Count_bin;


reg[7:0] Data_Previous1;


always@(negedge reset1 or posedge clk)
begin

if( ~reset1) begin

   Count_clk<=0;
   Count_bin<=0;
   Data_Previous1<=0ㄤ
   State1 <=0;
end
else begin
    
    Data_Previous1 <= Data1;
    
    case (State1)
    0:
    begin
      
        if(Count_clk >= 287 ) begin
        
            Count_clk<=0;
        
        end
        
        else begin
        
            Count_clk <= Count_clk + 1;
        
        end
        
        if(Count_clk == 0 )begin
            if(Data1==1)begin
                Count_bin <= Count_bin+1;
            end
            else begin
                Count_bin <= 0;
            end
        end
        
        if(Count_bin== 15 )begin
                State1 <= 1;
        end
        
        
    end
    1:
    begin
          
          
    end  
    default:
    begin
          
          
    end
       
    endcase
    
end

end

endmodule 


那要怎麼做呢,其實很簡單我們只要指向上一個觸發那瞬間的自己就是 上一個自己


Data_Previous1 <= Data1;

那怎麼寫判斷反轉呢
https://ithelp.ithome.com.tw/upload/images/20221004/201358627nBSY0Cymy.png

那就是


if(~Data_Previous1 & Data1 ) begin

    State1 <= 2;

end

那就通過 Start了

放進程式吧



module Rs232_test1(Data1,clk,reset1,Out1,En_out);
input Data1,reset1 ,clk;
output[7:0] Out1;
output En_out;

reg[7:0] State1;


reg[7:0] Count_clk;
reg[7:0] Count_bin;


reg[7:0] Data_Previous1;


always@(negedge reset1 or posedge clk)
begin

if( ~reset1) begin

   Count_clk<=0;
   Count_bin<=0;
   Data_Previous1<=0ㄤ
   State1 <=0;
end
else begin
    
    Data_Previous1 <= Data1;
    
    case (State1)
    0:
    begin
      
        if(Count_clk >= 287 ) begin
        
            Count_clk<=0;
        
        end
        
        else begin
        
            Count_clk <= Count_clk + 1;
        
        end
        
        if(Count_clk == 0 )begin
            if(Data1==1)begin
                Count_bin <= Count_bin+1;
            end
            else begin
                Count_bin <= 0;
            end
        end
        
        if(Count_bin== 15 )begin
                State1 <= 1;
        end
        
        
    end
    1:
    begin
          if(~Data_Previous1 & Data1 ) begin

            State1 <= 2;

          end
    end  
    default:
    begin
          
          
    end
       
    endcase
    
end

end

endmodule 


今天到這吧~


上一篇
[Day 20] Verilog E-1 難度丁 P2海域的解謎5 - Rs232訊號協議(選擇 Reg、設計初始化)
下一篇
[Day 22] Verilog E-1 難度丁 P2海域的消血2 - Rs232訊號協議 Data delay 再講一次 ( 設計輸出1.5 )
系列文
超簡單的 Verilog 入門講解30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言