一設計功能:(一)用兩個分頻模塊,實現16分頻,且讓輸入a 和b在16個系統時鐘內,相與一次。dom
|
(二)模塊化設計思想(結構化思惟)異步
拆分,即把一個系統劃分紅多個功能模塊,控制模塊,組合模塊。而後從功能模塊開始,按部就班一個個設計好,再把全部的模塊鏈接起來,實現系統功能。模塊化
|
二設計輸入spa
(一)頂層模塊:定義輸入輸出端口,實現各個模塊的鏈接經過例化 設計
//頂層模塊blog
module top(接口 input wire Clk,ci input wire Rst_n,開發 input wire a,input input wire b, output wire c );
wire p_flag;//connect po_flag0 to pi_flag0 wire flag;//connect po_flag to pi_flag //例化 div_clk2 div_clk2m0( .clk(Clk), .rst_n(Rst_n), .po_flag0(p_flag) );
div_clk1 div_clk1m0( .clk(Clk), .rst_n(Rst_n), .pi_flag0(p_flag), .po_flag(flag)
);
a_and_b a_and_bm0( . clk(Clk), . rst_n(Rst_n), . pi_flag(flag), . pi_a(a), . pi_b(b), . po_c(c) );
endmodule
|
(二)分頻模塊:兩個分頻模塊實現16分頻
//分頻模塊2實現四分頻並輸出一個分頻標誌信號 module div_clk2( input wire clk, input wire rst_n, output reg po_flag0 ); wire rst; reg [1:0] div_cnt; assign rst = ~rst_n;
//div cnt
always @(posedge clk)begin if(rst == 1'b1 )begin div_cnt <= 'd0; end else if (div_cnt == 'd3) begin div_cnt <= 'd0; end else div_cnt <= div_cnt + 1'b1;
end
//po_flag0 always @(posedge clk) begin if (rst == 1'b1 ) begin po_flag0<= 1'b0; end else if(div_cnt== 'd2)begin po_flag0 <= 1'b1; end else begin po_flag0 <= 1'b0; end end endmodule
//分頻模塊1在分頻模塊2的基礎上,實現16分頻並輸出對應的分頻標誌信號
module div_clk1( input wire clk, input wire rst_n, input wire pi_flag0, output reg po_flag
); wire rst; assign rst = ~rst_n;
//div_cnt under the pi_flag0 reg [1:0]div_cnt; always@(posedge clk) if(rst) div_cnt<=0; else if(div_cnt==2'd3) div_cnt<=0; else if(pi_flag0) div_cnt<=div_cnt+1'b1; else div_cnt<=div_cnt;
//po_flag always@(posedge clk) if(rst) po_flag<=0; else if(div_cnt==2'd3 & pi_flag0)//lack & pi_flag0 is error po_flag<=1'b1; else po_flag<=0; endmodule
|
(三)相與模塊
//相與模塊,在16分頻的標誌信號下,相與 module a_and_b( input wire clk, input wire rst_n, input wire pi_flag, input wire pi_a, input wire pi_b, output reg po_c ); wire rst; assign rst = ~rst_n; always@(posedge clk) if(rst==1'b1) po_c<=1'b0; else if(pi_flag==1'b1) po_c<=pi_a & pi_b; else po_c<=0;
endmodule
|
三總結
(一)常見疑問及答案
1.在不一樣模塊的信號,經過傳輸線連在一塊兒,那這些信號會有延時嘛(即變化實際不同)?
實際上,在不一樣模塊的同一信號如po_flag, pi_flag,flag,他們經過flag信號連在一塊兒,是同時變化的。
2.在什麼狀況下存在延時?
存在延時一個時鐘的會是在時序邏輯的always裏,以下面的賦值語句中
else if(div_cnt== 'd2)begin po_flag <= 1'b1; po_flag在仿真中,實際爲高電平在分頻計數值爲3. else if (pi_flag == 1'b1) begin po_c <= pi_a & pi_b; end 而在相與模塊裏,發生相與操做是在po_flag爲高後,再延遲一個時鐘,故相與在分頻計數值爲2後,延遲了兩個時鐘週期, |
3.注意下面這句易出錯
else if(div_cnt==2'd3 & pi_flag0)//lack & pi_flag0 is error
po_flag<=1'b1;
若缺乏後面的與條件,會持續四個時鐘週期,因爲div_cnt每四個時鐘更新。
(二)設計注意點
1.sublime列編輯:shift+鼠標右鍵。
2.賽靈思要求爲同步復位,故開發板是異步復位,則程序設計爲
wire rst;
assign rst = ~rst_n;
3.在例化,模塊的接口是輸入,能夠鏈接wire或reg型變量。但模塊的接口是輸出,必須鏈接wire型。
4.基本語法準則:即always賦值的輸出信號,只能爲reg型。而assign賦值的輸出信號,只能爲wire型。
(三)仿真
`timescale 1ns/1ns `define clk_period 20 module top_tb(); reg clk; reg rst_n; reg a; reg b; wire c; top top_m0( .Clk(clk), .Rst_n(rst_n), .a(a), .b(b), .c(c) );
initial clk =1; always#(`clk_period/2) clk = ~clk; initial begin rst_n =0; a=0; b=0; #(`clk_period*2); rst_n =1; #(`clk_period*40); rst_n = 0; #(`clk_period*12); $stop;
end always#(`clk_period*2) a = {$random}; always#(`clk_period*2) b= {$random};
endmodule //波形:
|