一些简单组合逻辑电路的verilog实现

HDLBits

输出接地

一些简单组合逻辑电路的verilog实现

module top_module (
    output out);
	assign out = 1'b0;
endmodule

out_anotb: a and-not b

一些简单组合逻辑电路的verilog实现

module top_module (
    input in1,
    input in2,
    output out);
	assign out = in1 &~ in2;
endmodule

常用门电路汇总

  • out_and: a and b
  • out_or: a or b
  • out_xor: a xor b
  • out_nand: a nand b
  • out_nor: a nor b
  • out_xnor: a xnor b
  • out_anotb: a and-not b
module top_module( 
    input a, b,
    output out_and,
    output out_or,
    output out_xor,
    output out_nand,
    output out_nor,
    output out_xnor,
    output out_anotb
);
	assign out_and = a & b;
    assign out_or = a | b;
    assign out_xor = a ^b;
    assign out_nand = ~(a & b);
    assign out_nor = ~(a | b);
    assign out_xnor = a ~^ b;
    assign out_anotb = a &~ b;
endmodule

一些简单组合逻辑电路的verilog实现

Ringer

Suppose you are designing a circuit to control a cellphone's ringer and vibration motor. Whenever the phone needs to ring from an incoming call (input ring), your circuit must either turn on the ringer (output ringer = 1) or the motor (output motor = 1), but not both. If the phone is in vibrate mode (input vibrate_mode = 1), turn on the motor. Otherwise, turn on the ringer.

Try to use only assign statements, to see whether you can translate a problem description into a collection of logic gates.

一些简单组合逻辑电路的verilog实现

module top_module(
	input ring, 
	input vibrate_mode,
	output ringer,
	output motor
);
	
	// When should ringer be on? When (phone is ringing) and (phone is not in vibrate mode)
	assign ringer = ring & ~vibrate_mode;
	
	// When should motor be on? When (phone is ringing) and (phone is in vibrate mode)
	assign motor = ring & vibrate_mode;
	
endmodule

 一些简单组合逻辑电路的verilog实现

Thermostat 

A heating/cooling thermostat controls both a heater (during winter) and an air conditioner (during summer). Implement a circuit that will turn on and off the heater, air conditioning, and blower fan as appropriate.

The thermostat can be in one of two modes: heating (mode = 1) and cooling (mode = 0). In heating mode, turn the heater on when it is too cold (too_cold = 1) but do not use the air conditioner. In cooling mode, turn the air conditioner on when it is too hot (too_hot = 1), but do not turn on the heater. When the heater or air conditioner are on, also turn on the fan to circulate the air. In addition, the user can also request the fan to turn on (fan_on = 1), even if the heater and air conditioner are off.

Try to use only assign statements, to see whether you can translate a problem description into a collection of logic gates.

module top_module(
	input too_cold, 
	input too_hot,
	input mode,
	input fan_on,
	output heater,
	output aircon,
	output fan
);
	// Reminder: The order in which you write assign statements doesn't matter. 
	// assign statements describe circuits, so you get the same circuit in the end
	// regardless of which portion you describe first.

	// Fan should be on when either heater or aircon is on, and also when requested to do so (fan_on = 1).
	assign fan = heater | aircon | fan_on;
	
	// Heater is on when it's too cold and mode is "heating".
	assign heater = (mode & too_cold);
	
	// Aircon is on when it's too hot and mode is not "heating".
	assign aircon = (~mode & too_hot);
	
	// * Unlike real thermostats, there is no "off" mode here.
	
endmodule

一些简单组合逻辑电路的verilog实现

Gatesv

You are given a four-bit input vector in[3:0]. We want to know some relationships between each bit and its neighbour:

  • out_both: Each bit of this output vector should indicate whether both the corresponding input bit and its neighbour to the left (higher index) are '1'. For example, out_both[2] should indicate if in[2] and in[3] are both 1. Since in[3] has no neighbour to the left, the answer is obvious so we don't need to know out_both[3].
  • out_any: Each bit of this output vector should indicate whether any of the corresponding input bit and its neighbour to the right are '1'. For example, out_any[2] should indicate if either in[2] or in[1] are 1. Since in[0] has no neighbour to the right, the answer is obvious so we don't need to know out_any[0].
  • out_different: Each bit of this output vector should indicate whether the corresponding input bit is different from its neighbour to the left. For example, out_different[2] should indicate if in[2] is different from in[3]. For this part, treat the vector as wrapping around, so in[3]'s neighbour to the left is in[0].
module top_module (
	input [3:0] in,
	output [2:0] out_both,
	output [3:1] out_any,
	output [3:0] out_different
);

	// Use bitwise operators and part-select to do the entire calculation in one line of code
	// in[3:1] is this vector:   					 in[3]  in[2]  in[1]
	// in[2:0] is this vector:   					 in[2]  in[1]  in[0]
	// Bitwise-OR produces a 3 bit vector.			   |      |      |
	// Assign this 3-bit result to out_any[3:1]:	o_a[3] o_a[2] o_a[1]

	// Thus, each output bit is the OR of the input bit and its neighbour to the right:
	// e.g., out_any[1] = in[1] | in[0];	
	// Notice how this works even for long vectors.
	assign out_any = in[3:1] | in[2:0];

	assign out_both = in[2:0] & in[3:1];
	
	// XOR 'in' with a vector that is 'in' rotated to the right by 1 position: {in[0], in[3:1]}
	// The rotation is accomplished by using part selects[] and the concatenation operator{}.
	assign out_different = in ^ {in[0], in[3:1]};
	
endmodule

一些简单组合逻辑电路的verilog实现

 Mux2to1

Create a one-bit wide, 2-to-1 multiplexer. When sel=0, choose a. When sel=1, choose b.

module top_module( 
    input a, b, sel,
    output out ); 
    always @(*) begin
        if(sel) out = b;
        else out = a;
    end
endmodule
/*
module top_module (
	input a,
	input b,
	input sel,
	output out
);

	assign out = (sel & b) | (~sel & a);	// Mux expressed as AND and OR
	
	// Ternary operator is easier to read, especially if vectors are used:
	// assign out = sel ? b : a;
	
endmodule

or

module top_module( 
    input a, b, sel,
    output out ); 
    assign out = sel?b:a;
endmodule
*/

一些简单组合逻辑电路的verilog实现

Mux9to1v 

Create a 16-bit wide, 9-to-1 multiplexer. sel=0 chooses a, sel=1 chooses b, etc. For the unused cases (sel=9 to 15), set all output bits to '1'.

module top_module( 
    input [15:0] a, b, c, d, e, f, g, h, i,
    input [3:0] sel,
    output [15:0] out );
    always @(*) begin
        case(sel)
            4'd0: out = a;
            4'd1: out = b;
            4'd2: out = c;
            4'd3: out = d;
            4'd4: out = e;
            4'd5: out = f;
            4'd6: out = g;
            4'd7: out = h;
            4'd8: out = i;
            default: out = 16'hffff;//out = '1; 
//'1 is a special literal syntax for a number with all bits set to 1.
// '0, 'x, and 'z are also valid.
        endcase
    end
endmodule

一些简单组合逻辑电路的verilog实现

Mux256to1 

Create a 1-bit wide, 256-to-1 multiplexer. The 256 inputs are all packed into a single 256-bit input vector. sel=0 should select in[0], sel=1 selects bits in[1], sel=2 selects bits in[2], etc.

hint

Vector indices can be variable, as long as the synthesizer can figure out that the width of the bits being selected is constant. In particular, selecting one bit out of a vector using a variable index will work.

module top_module( 
    input [255:0] in,
    input [7:0] sel,
    output out );
    assign out = in[sel];
endmodule

全加器

Create a full adder. A full adder adds three bits (including carry-in) and produces a sum and carry-out.

module top_module( 
    input a, b, cin,
    output cout, sum );
    assign sum = a^b^cin;
    assign cout = a&b | (a^b)&cin;
endmodule

一些简单组合逻辑电路的verilog实现

 Adder

Implement the following circuit:

一些简单组合逻辑电路的verilog实现

module top_module (
	input [3:0] x,
	input [3:0] y,
	output [4:0] sum
);

	// This circuit is a 4-bit ripple-carry adder with carry-out.
	assign sum = x+y;	// Verilog addition automatically produces the carry-out bit.

	// Verilog quirk: Even though the value of (x+y) includes the carry-out, (x+y) is still considered to be a 4-bit number (The max width of the two operands).
	// This is correct:
	// assign sum = (x+y);
	// But this is incorrect:
	// assign sum = {x+y};	// Concatenation operator: This discards the carry-out
endmodule

Kmap1

一些简单组合逻辑电路的verilog实现

Try to simplify the k-map before coding it. Try both product-of-sums and sum-of-products forms. We can't check whether you have the optimal simplification of the k-map. But we can check if your reduction is equivalent, and we can check whether you can translate a k-map into a circuit.

module top_module(
	input a, 
	input b,
	input c,
	output out
);

	// SOP form: Three prime implicants (1 term each), summed.
	// POS form: One prime implicant (of 3 terms)
	// In this particular case, the result is the same for both SOP and POS.
	assign out = (a | b | c);
	
endmodule

 一些简单组合逻辑电路的verilog实现

Kmap2 

一些简单组合逻辑电路的verilog实现

Try to simplify the k-map before coding it. Try both product-of-sums and sum-of-products forms. We can't check whether you have the optimal simplification of the k-map. But we can check if your reduction is equivalent, and we can check whether you can translate a k-map into a circuit.

module top_module(
    input a,
    input b,
    input c,
    input d,
    output out  ); 
    assign out = (~a & ~d) | (~b & ~c) | (c & d & b) | (c & d & a);
endmodule

 一些简单组合逻辑电路的verilog实现

Kmap3 

一些简单组合逻辑电路的verilog实现

module top_module(
    input a,
    input b,
    input c,
    input d,
    output out  ); 
    assign out = a | (c & ~b);
endmodule

一些简单组合逻辑电路的verilog实现

Kmap4 

一些简单组合逻辑电路的verilog实现

module top_module(
    input a,
    input b,
    input c,
    input d,
    output out  ); 
    assign out = (a ^ b) ^ (c ^ d);
//out = (~a & b & ~c & ~d) | (a & ~b & ~c & ~d) |  (~a & ~b & ~c & d) | 
//       (a & b & ~c & d) | (~a & b & c & d) |  (a & ~b & c & d) |  
//        (~a & ~b & c & ~d) | (a & b & c & ~d);
endmodule

 一些简单组合逻辑电路的verilog实现

K-map implemented with a multiplexer 

一些简单组合逻辑电路的verilog实现

一些简单组合逻辑电路的verilog实现

You are implementing just the portion labelled top_module, such that the entire circuit (including the 4-to-1 mux) implements the K-map.

module top_module (
    input c,
    input d,
    output [3:0] mux_in
); 
    always @(*) begin
        mux_in[0] = c | d;
        mux_in[1] = 0;
        mux_in[3] = c & d;
        mux_in[2] = (~c & ~d) | (c & ~d);
    end
	// After knowing how to split the truth table into four columns,
	// the rest of this question involves implementing logic functions
	// using only multiplexers (no other gates).
	// I will use the conditional operator for each 2-to-1 mux: (s ? a : b)
	//assign mux_in[0] = (c ? 1 : (d ? 1 : 0));    2 muxes: c|d
	//assign mux_in[1] = 0;			       No muxes:  0
	//assign mux_in[2] = d ? 0 : 1;		       1 mux:    ~d
	//assign mux_in[3] = c ? (d ? 1 : 0) : 0;      2 muxes: c&d
endmodule

256-to-1 4-bit multiplexer

Create a 4-bit wide, 256-to-1 multiplexer. The 256 4-bit inputs are all packed into a single 1024-bit input vector. sel=0 should select bits in[3:0], sel=1 selects bits in[7:4], sel=2 selects bits in[11:8], etc.

module top_module( 
    input [1023:0] in,
    input [7:0] sel,
    output [3:0] out );
    assign out = in[sel * 4 +: 4];
    //assign out = {in[sel * 4 + 3], in[sel * 4 + 2], in[sel * 4 + 1], in[sel * 4]};
endmodule

Signed addition overflow

Assume that you have two 8-bit 2's complement numbers, a[7:0] and b[7:0]. These numbers are added to produce s[7:0]. Also compute whether a (signed) overflow has occurred.

module top_module (
    input [7:0] a,
    input [7:0] b,
    output [7:0] s,
    output overflow
); //
    assign s = a + b;
 	assign overflow = a[7] & b[7] & ~s[7] | ~a[7] & ~b[7] & s[7];
    // assign s = ...
    // assign overflow = ...

endmodule

一些简单组合逻辑电路的verilog实现

 

上一篇:前缀和-prefixsum


下一篇:03_MapReduce框架原理_3.11 MapReduce 内核源码解析