辦網站需流程網絡推廣一個月的收入
LV9_使用子模塊實現三輸入數的大小比較
題目來源于??途W
[??途W在線編程_Verilog篇_Verilog快速入門 (nowcoder.com)](https://www.nowcoder.com/exam/oj?page=1&tab=Verilog篇&topicId=301)
題目
描述
在數字芯片設計中,通常把完成特定功能且相對獨立的代碼編寫成子模塊,在需要的時候再在主模塊中例化使用,以提高代碼的可復用性和設計的層次性,方便后續(xù)的修改。
請編寫一個子模塊,將輸入兩個8bit位寬的變量data_a,data_b,并輸出data_a,data_b之中較小的數。并在主模塊中例化,實現輸出三個8bit輸入信號的最小值的功能。
子模塊的信號接口圖如下:
主模塊的信號接口圖如下:
輸入描述:
clk:系統(tǒng)時鐘
rst_n:異步復位信號,低電平有效
a,b,c:8bit位寬的無符號數
輸出描述:
d:8bit位寬的無符號數,表示a,b,c中的最小值
編寫子模塊
在Verilog中,可以使用module
關鍵字編寫子模塊。子模塊是一種將較大的電路拆分為模塊化部分的方法,使代碼更易于維護和重復使用。
以下是一個簡單的示例,展示了如何編寫一個加法器子模塊:
module Adder(input [3:0] A, input [3:0] B, output [4:0] Sum
);assign Sum = A + B;
endmodule
通過將子模塊實例化到另一個模塊中,可以在主模塊中使用子模塊。
下面是一個示例,展示了如何實例化并使用上述的加法器子模塊:
module Top;// 輸入和輸出端口聲明reg [3:0] A;reg [3:0] B;wire [4:0] Sum;// 子模塊實例化Adder adder_inst(.A(A), .B(B), .Sum(Sum));// 在這里可以使用子模塊的輸出Sum// ...endmodule
代碼思路
例化一個模塊,該模塊比較兩個輸入的大小,并輸出較小的數。
例化兩次該模塊,實現三個數的比較。
注:
采用時序邏輯例化兩次子模塊時,第一個例化的最小值經過一個時鐘周期才能得到,
此時若再拿去與第三個數比較大小進行第二次例化時,第三個數已經不是上個周期的數了,
解決辦法就是將第三個數緩存一個周期,再進行第二次例化子模塊,結果可以通過測試。
代碼
`timescale 1ns/1ns
module main_mod(input clk,input rst_n,input [7:0]a,input [7:0]b,input [7:0]c,output [7:0]d //由圖可知,a,b,c,d全為wire型);wire [7:0] min_ab;//第一次例化,比較a,b的大小compare u_compare(.clk(clk),.rst_n(rst_n),.data_a(a),.data_b(b),.data_c(min_ab));
/*采用時序邏輯例化兩次子模塊時,第一個例化的最小值經過一個時鐘周期才能得到,
此時若再拿去與第三個數比較大小進行第二次例化時,第三個數已經不是上個周期的數了,
解決辦法就是將第三個數緩存一個周期,再進行第二次例化子模塊,結果可以通過測試。
*/reg [7:0] c_r; //將c的值存儲起來always @(posedge clk or negedge rst_n) beginif(!rst_n)c_r <= 0;else c_r <= c;end//第二次例化,比較a,b,c的大小compare u_compare_2(.clk(clk),.rst_n(rst_n),.data_a(min_ab),.data_b(c_r),.data_c(d));
endmodule//子模塊:比較data_a,data_b的大小,并且輸出較小的數
module compare(input clk,input rst_n,input [7:0]data_a,input [7:0]data_b,output [7:0]data_c
); reg [7:0] result; //定義一個reg型,將比較結果存起來always @(posedge clk or negedge rst_n) beginif(!rst_n)result <=0;else beginif(data_a > data_b)result <= data_b;else if(data_a <= data_b)result <= data_a;end endassign data_c = result;
endmodule