# verilog 參數化除頻器 先上code ```=verilog module div_general( input clk, input reset, output reg div_clk ); //parameter parameter counter_width=3; parameter div_num=6; //decided cycle of counter reg [counter_width-1:0] cycle; always@(*) begin if (div_num%2) cycle=div_num/2+1'd1; //odd else cycle=div_num/2; //even end //div ////posedge clk reg pos_clk; reg [counter_width-1:0] pos_counter; //counter always@(posedge clk) begin if (reset) pos_counter<=1'd0; else if (pos_counter==div_num-1) pos_counter<=1'd0; else pos_counter<=pos_counter+1'd1; end //div always@(posedge clk) begin if (reset) pos_clk<=1'd0; else if (pos_counter>=cycle) pos_clk<=1'd1; else pos_clk<=1'd0; end //negedge clk reg neg_clk; reg [counter_width-1:0] neg_counter; //counter always@(negedge clk) begin if (reset) neg_counter<=1'd0; else if (neg_counter==div_num-1) neg_counter<=1'd0; else neg_counter<=neg_counter+1'd1; end //div always@(negedge clk) begin if (reset) neg_clk<=1'd0; else if (neg_counter>=cycle) neg_clk<=1'd1; else neg_clk<=1'd0; end //output combinational always@(*) begin if (div_num%2) div_clk=pos_clk|neg_clk; //odd else div_clk=pos_clk; //even end endmodule ``` ## 參數的輸入 功能就是輸入你要的除N電路(輸入N) 然後再給為了這個N counter相對應的bit數 輸出就是除頻結果 ```=verilog //parameter parameter counter_width=3; parameter div_num=6; ``` ## 參數化計數器所使用到的counter 基本上只要除奇數的電路觀念懂了 後面其實一樣 除N電路可以這樣理解: counter是從0數到N-1 寫法如下 正緣part ```=verilog //counter always@(posedge clk) begin if (reset) pos_counter<=1'd0; else if (pos_counter==div_num-1) pos_counter<=1'd0; else pos_counter<=pos_counter+1'd1; end ``` 負緣part ```=verilog //counter always@(negedge clk) begin if (reset) neg_counter<=1'd0; else if (neg_counter==div_num-1) neg_counter<=1'd0; else neg_counter<=neg_counter+1'd1; end ``` ## 除頻的實作 要先判定N的奇偶性 當N為奇數時 輸出的clk(不管是正緣的part 還是負緣的part) 是從N/2+1開始轉成1 前面都是0 e.g. 當N為7時 counter數0 1 2 3 都是輸出0 數4 5 6 都是輸出1 當N為偶數時就比較簡單 輸出的clk從N/2開始轉成1 e.g. 當N為4時 counter數0 1 輸出0 數2 3 輸出1 我這邊用cycle把交界的值存起來 ```=verilog //decided cycle of counter reg [counter_width-1:0] cycle; always@(*) begin if (div_num%2) cycle=div_num/2+1'd1; //odd else cycle=div_num/2; //even end ``` 然後是正緣跟負緣的除頻 ```=verilog //div always@(posedge clk) begin if (reset) pos_clk<=1'd0; else if (pos_counter>=cycle) pos_clk<=1'd1; else pos_clk<=1'd0; end ``` ```=verilog //div always@(negedge clk) begin if (reset) neg_clk<=1'd0; else if (neg_counter>=cycle) neg_clk<=1'd1; else neg_clk<=1'd0; end ``` ## 輸出的部分 輸出的話再判定一次N的奇偶性 當N為奇數 輸出clk=正緣負緣or出來的結果 當N為偶數 就輸出正緣的clk就好 ```=verilog //output combinational always@(*) begin if (div_num%2) div_clk=pos_clk|neg_clk; //odd else div_clk=pos_clk; //even end ``` ## 結尾 大概就是以上這些觀念 然後code照上面的邏輯小心一點寫這樣 這個code是我100%的單純想法 之後應該會更新一下高手的寫法 看有什麼不同去比較看看 會有第二part的
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up