hdlbits答案:Module cseladd、Module addsub、Alwaysblock1、Alwaysblock2、Always if、Always if2、Always case

10 篇文章 0 订阅
9 篇文章 0 订阅

Module cseladd

In this exercise, you are provided with the same module add16 as the previous exercise, which adds two 16-bit numbers with carry-in and produces a carry-out and 16-bit sum. You must instantiate three of these to build the carry-select adder, using your own 16-bit 2-to-1 multiplexer.

Connect the modules together as shown in the diagram below. The provided module add16 has the following declaration:

module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );

 

module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
    wire cout1,cout2,cout3;
    wire [15:0]sum2,sum3;
    add16 inst1(a[15:0],b[15:0],1'b0,sum[15:0],cout1);
    add16 inst2(a[31:16],b[31:16],1'b0,sum2,cout2);
    add16 inst3(a[31:16],b[31:16],1'b1,sum3,cout3);
    assign sum[31:16]=cout1?sum3:sum2;
endmodule

 这道题没啥说的,就最后用一个assign选择一下,比直接用always@要少几行代码量。

Module addsub

module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );

Use a 32-bit wide XOR gate to invert the b input whenever sub is 1. (This can also be viewed as b[31:0] XORed with sub replicated 32 times. See replication operator.). Also connect the sub input to the carry-in of the adder.

module top_module(
    input [31:0] a,
    input [31:0] b,
    input sub,
    output [31:0] sum
);
        
    wire [31:0] b_q;
    wire cout;
    
    assign b_q = b^{32{sub}}; //使用32位的异或门。
    
    add16 a0(a[15:0],b_q[15:0],sub,sum[15:0],cout);
    add16 a1(a[31:16],b_q[31:16],cout,sum[31:16],);

endmodule


注意下那个异或门,说的是sub信号要展宽到32bite。

Alwaysblock1

Build an AND gate using both an assign statement and a combinational always block. (Since assign statements and combinational always blocks function identically, there is no way to enforce that you're using both methods. But you're here for practice, right?...)

意思是使用组合逻辑块或者assign 写一个与门电路。

// synthesis verilog_input_version verilog_2001
module top_module(
    input a, 
    input b,
    output wire out_assign,
    output reg out_alwaysblock
);
	assign out_assign = a & b ;
    always @(*) begin
        out_alwaysblock = a & b ;
    end
endmodule

Alwaysblock2

在这道题中,前两个输出都是纯粹的组合逻辑,后面一个是组合逻辑经过时序寄存一拍输出。

// synthesis verilog_input_version verilog_2001
module top_module(
    input clk,
    input a,
    input b,
    output wire out_assign,
    output reg out_always_comb,
    output reg out_always_ff   );
//-----------------------------------
assign out_assign=a^b;
//-----------------------------------
always@(*)begin 
	out_always_comb=a^b;
end 
//-----------------------------------
always@(posedge clk)begin
	out_always_ff<= out_always_comb;
end 
endmodule

Always if

A bit of practice

Build a 2-to-1 mux that chooses between a and b. Choose b if both sel_b1 and sel_b2 are true. Otherwise, choose a. Do the same twice, once using assign statements and once using a procedural if statement.

// synthesis verilog_input_version verilog_2001
module top_module(
    input a,
    input b,
    input sel_b1,
    input sel_b2,
    output wire out_assign,
    output reg out_always   ); 
assign out_assign=(sel_b1&sel_b2)?b:a;
always@(*)begin 
	if ((sel_b1&sel_b2)==1'b1)
		out_always=b;
	else
		out_always=a;
end 
endmodule

Always if2

Demonstration

The following code contains incorrect behaviour that creates a latch. Fix the bugs so that you will shut off the computer only if it's really overheated, and stop driving if you've arrived at your destination or you need to refuel.

// synthesis verilog_input_version verilog_2001
module top_module (
    input      cpu_overheated,
    output reg shut_off_computer,
    input      arrived,
    input      gas_tank_empty,
    output reg keep_driving  ); //

    always @(*) begin
        if (cpu_overheated)
           shut_off_computer = 1;
		else
			shut_off_computer = 0;
    end

    always @(*) begin
        if (~arrived)
            keep_driving = ~gas_tank_empty;
		else 
			keep_driving=0;
    end

endmodule

这道题的意思是条件分支要完备,除非是特别需要所以故意的,否则尽量避免生成锁存器。

Always case

A bit of practice

Case statements are more convenient than if statements if there are a large number of cases. So, in this exercise, create a 6-to-1 multiplexer. When sel is between 0 and 5, choose the corresponding data input. Otherwise, output 0. The data inputs and outputs are all 4 bits wide.

Be careful of inferring latches (See.always_if2)

// synthesis verilog_input_version verilog_2001
module top_module ( 
    input [2:0] sel, 
    input [3:0] data0,
    input [3:0] data1,
    input [3:0] data2,
    input [3:0] data3,
    input [3:0] data4,
    input [3:0] data5,
    output reg [3:0] out   );//

    always@(*) begin  // This is a combinational circuit
        case(sel)
		3'd0:		out=data0;
		3'd1:		out=data1;
		3'd2:		out=data2;
		3'd3:		out=data3;
		3'd4:		out=data4;
		3'd5:		out=data5;
		default:    out =0;
		endcase
    end
endmodule

写一段组合逻辑case语句,大于5的输出默认值0。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值