一些简单组合逻辑电路的verilog实现
作者:互联网
输出接地
module top_module (
output out);
assign out = 1'b0;
endmodule
out_anotb: a and-not b
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
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.
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
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
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
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
*/
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
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
Adder
Implement the following circuit:
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
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
Kmap2
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
Kmap3
module top_module(
input a,
input b,
input c,
input d,
output out );
assign out = a | (c & ~b);
endmodule
Kmap4
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
K-map implemented with a multiplexer
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
标签:组合,module,逻辑电路,verilog,output,input,sel,assign,out 来源: https://blog.csdn.net/qq_46198448/article/details/122255950