HDL_BITS 练习(四)

这篇博客讨论了在Verilog中调用子模块时,使用端口位置(by position)和端口名字(by name)两种方式的优缺点。by position方式直观但不易于维护,若端口顺序改变则需更新所有实例;by name方式允许灵活的端口顺序,但需确保名字对应正确。示例展示了不同情况下的模块调用,包括加法器和触发器的设计,强调了在复杂设计中灵活性和可读性的平衡。
摘要由CSDN通过智能技术生成

module

1,分别用模块端口名字(name),模块端口参数位置(position)实现调用子模块。

by position:One drawback of this syntax is that if the module's port list changes, all instantiations of the module will also need to be found and changed to match the new module.

by name:Notice how the ordering of ports is irrelevant here because the connection will be made to the correct name, regardless of its position in the sub-module's port list

总的说,position 比较符合C语言习惯易懂,但是参数位置不能随便改。name法则对参数位置随便

module top_module ( input a, input b, output out );
    mod_a mod1(.in1(a),.in2(b),.out(out));//模块名字 参数位置不受限制
    //mod_a mod1(.out(out),.in1(a),.in2(b));
    //mod_a mod1(a,b,out);//模块位置,随参数位置变化变化
endmodule

2 module by position

module top_module ( 
    input a, 
    input b, 
    input c,
    input d,
    output out1,
    output out2
);
    mod_a (out1,out2,a,b,c,d);

endmodule

3 module by name:

module top_module ( 
    input a, 
    input b, 
    input c,
    input d,
    output out1,
    output out2
);
    mod_a(.in1(a),.in2(b),.in3(c),.in4(d),.out1(out1),.out2(out2));

endmodule
//可见参数一一对应,位置不需考虑。

4 module shift

由图片可知需要初始化三个D触发器,模块内部有5个信号线,外部输入的CLK,D 信号,还有输出信号q,还有内部三个触发器之间通信的2个信号线。命名为wire Q1,Q2。

 module top_module ( input clk, input d, output q );
    wire Q1,Q2;
    my_dff(.clk(clk),.d(d),.q(Q1));
    my_dff(.clk(clk),.d(Q1),.q(Q2));
    my_dff(.clk(clk),.d(Q2),.q(q));
endmodule

5 module shift8

3个8位D触发器,之后有一个4选一(用always@(*))

类似上个实验,只是输入信号变成8位vector ,输出多了个4选一

module top_module ( 
    input clk, 
    input [7:0] d, 
    input [1:0] sel, 
    output [7:0] q 
);
    wire[7:0]q1,q2,q3;
    my_dff8 mod1(.clk(clk),.d(d),.q(q1));
    my_dff8 mod2(.clk(clk),.d(q1),.q(q2));
    my_dff8 mod3(.clk(clk),.d(q2),.q(q3));
    
    always@(*)begin
        case(sel)
            0:q=d;
            1:q=q1;
            2:q=q2;
            3:q=q3;
        endcase
    end
                
            

endmodule

6 module adder1

加法器程序 adder1

引用的模块add16在网站上有,但是无需编写提交,主模块直接引用add16即可。

module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
    wire cin1,cin2,cout1,cout2;
    wire [15:0] sum1,sum2;
    assign cin1=0;
    assign cin2=cout1;
    add16 instance1(.a(a[15:0]), .b(b[15:0]), .cin(cin1), .cout(cout1), .sum(sum1));
    add16 instance2(.a(a[31:16]), .b(b[31:16]), .cin(cin2), .cout(cout2), .sum(sum2));
    assign sum = {sum2, sum1};    //[31:0] sum={sum2,sum1};
endmodule

7 加法器程序fadd:

32位加法器,由两个add16 modules 组成,而每个module add16则是由1位全加器级联而成。

需要初始化1位全加器程序。

全加器提示:

Full adder equations:
sum = a ^ b ^ cin
cout = a&b | a&cin | b&cin

所以综合上次加法器的练习,添加add1 module

module top_module (
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);//
    wire cin1,cin2,cout1,cout2;
    wire [15:0] sum1,sum2;
    assign cin1=0;
    assign cin2=cout1;
    add16 instance1(.a(a[15:0]), .b(b[15:0]), .cin(cin1), .cout(cout1), .sum(sum1));
    add16 instance2(.a(a[31:16]), .b(b[31:16]), .cin(cin2), .cout(cout2), .sum(sum2));
    assign sum = {sum2, sum1};    //[31:0] sum={sum2,sum1}; 
endmodule
module add1 ( input a, input b, input cin,   output sum, output cout );

// Full adder module here
    assign sum = a ^ b ^ cin;
    assign cout = a&b | a&cin | b&cin;   

endmodule

8 加法器的改进

之前练习的加法器有着较长的延时,所以针对对这情况进行了改进。三个16 adder加法器并行处理

一个处理a,b的【15:0】位相加看有无进位,

assign cout = a&b | a&cin | b&cin;   

另外两个处理cin=1,0时候结果。

最后用2选一来输出结果。

module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);

    wire cin1, cout1, cin2, cout2, cin3, cout3;
    wire [15:0] sum1, sum2, sum3, sum4;
    assign cin1 = 0;//检查是否需要进位
    assign cin2 = 0;//cin=0
    assign cin3 = 1;//cin=1
    
    add16 instance1(.a(a[15:0]), .b(b[15:0]), .cin(cin1), .cout(cout1), .sum(sum1));
    add16 instance2(.a(a[31:16]), .b(b[31:16]), .cin(cin2), .cout(cout2), .sum(sum2));
    add16 instance3(.a(a[31:16]), .b(b[31:16]), .cin(cin3), .cout(cout3), .sum(sum3));
    
    always @(*) begin
        case(cout1)
            0 : sum4= sum2;//无需进位,选sum2
            1 : sum4 = sum3;//需要进位,选择sum3
        endcase
    end
    
    assign sum = {sum4, sum1};//组合逻辑得出结果
    
endmodule

9 加减器


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值