-----37. Conditional -----

Problem Statement

Given four unsigned numbers, find the minimum. Unsigned numbers can be compared with standard comparison operators (a < b). Use the conditional operator to make two-way min circuits, then compose a few of them to create a 4-way min circuit. You’ll probably want some wire vectors for the intermediate results.

Expected solution length: Around 5 lines.

Answer

1
2
3
4
5
6
7
8
9
10
11
module top_module (
input [7:0] a, b, c, d,
output [7:0] min);//

wire [7:0] intermediate_result1, intermediate_result2, intermediate_result3;
assign intermediate_result1 = (a < b)? a : b;
assign intermediate_result2 = (c < intermediate_result1)? c : intermediate_result1;
assign intermediate_result3 = (d < intermediate_result2)? d : intermediate_result2;
assign min = intermediate_result3;

endmodule

Note: Ternary conditional operator(三目运算符)

  • Ternary conditional operator: (condition ? if_true : if_false)
  • Example: (0 ? 3 : 5) // This is 5 because the condition is false.

-----38. Reduction -----

Problem Statement

Parity checking(奇偶校验) is often used as a simple method of detecting errors when transmitting data through an imperfect channel. Create a circuit that will compute a parity bit for a 8-bit byte (which will add a 9th bit to the byte). We will use “even” parity(偶校验), where the parity bit is just the XOR of all 8 data bits.

Expected solution length: Around 1 line.

Answer

1
2
3
4
5
6
7
8
9
module top_module (
input [7:0] in,
output parity);

assign parity = ^ in[7:0];
// other way: assign parity = ^ in;

endmodule

Note: The reduction operators

  • & a[3:0] // AND: a[3]&a[2]&a[1]&a[0]. Equivalent to (a[3:0] == 4’hf)
  • | b[3:0] // OR: b[3]|b[2]|b[1]|b[0]. Equivalent to (b[3:0] != 4’h0)
  • ^ c[2:0] // XOR: c[2]^c[1]^c

-----39. Gates100 -----

Problem Statement

Build a combinational circuit with 100 inputs, in[99:0].

There are 3 outputs:

  • out_and: output of a 100-input AND gate.
  • out_or: output of a 100-input OR gate.
  • out_xor: output of a 100-input XOR gate.

Answer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module top_module( 
input [99:0] in,
output out_and,
output out_or,
output out_xor
);

assign out_and = & in[99:0];
assign out_or = | in[99:0];
assign out_xor = ^ in[99:0];
//other way:
//assign out_and = & in;
//assign out_or = | in;
//assign out_xor = ^ in;

endmodule

-----40. Vector100r -----

Problem Statement

Given a 100-bit input vector [99:0], reverse its bit ordering.

Answer

1
2
3
4
5
6
7
8
9
10
11
12
13
module top_module( 
input [99:0] in,
output reg [99:0] out
);

integer i;
always @(*) begin
for(i = 0; i <= 99; i = i + 1)begin
out[i] = in[99 - i];
end
end

endmodule

-----41. Popcount255 -----

Problem Statement

A “population count” circuit counts the number of '1’s in an input vector. Build a population count circuit for a 255-bit input vector.

Answer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module top_module( 
input [254:0] in,
output [7:0] out );

integer i;
always @(*) begin
out = 8'd0;
for(i = 0; i <= 254; i = i + 1)begin
if(in[i] == 1'b1)
out = out + 1;
end
end

endmodule

-----42. Adder100i -----

Problem Statement

Create a 100-bit binary ripple-carry adder by instantiating 100 full adders. The adder adds two 100-bit numbers and a carry-in to produce a 100-bit sum and carry out. To encourage you to actually instantiate full adders, also output the carry-out from each full adder in the ripple-carry adder. cout[99] is the final carry-out from the last full adder, and is the carry-out you usually see.

Answer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module top_module( 
input [99:0] a, b,
input cin,
output [99:0] cout,
output [99:0] sum );

genvar i;
generate
for(i = 0; i <= 99; i = i + 1)begin: add100
if(i == 0)
assign {cout[i], sum[i]} = a[i] + b[i] + cin;
else
assign {cout[i], sum[i]} = a[i] + b[i] + cout[i-1];
end
endgenerate

endmodule

(提示:用always也可以)

-----43. Bcdadd100 -----

Problem Statement

You are provided with a BCD one-digit adder named bcd_fadd that adds two BCD digits and carry-in, and produces a sum and carry-out.

1
2
3
4
5
6
module bcd_fadd {
input [3:0] a,
input [3:0] b,
input cin,
output cout,
output [3:0] sum );

Instantiate 100 copies of bcd_fadd to create a 100-digit BCD ripple-carry adder. Your adder should add two 100-digit BCD numbers (packed into 400-bit vectors) and a carry-in to produce a 100-digit sum and carry out.

Answer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
module bcd_fadd (
input [3:0] a,
input [3:0] b,
input cin,
output cout,
output [3:0] sum );
//...
endmodule

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

wire [99:0] io;
genvar i;
generate
for(i = 99; i >= 0; i = i - 1)begin: bcd400
if(i == 0) //最低位
bcd_fadd instance_low (.a(a[4*i+3 : 4*i]), .b(b[4*i+3 : 4*i]), .cin(cin), .cout(io[i]), .sum(sum[4*i+3 : 4*i]));
else if(i == 99) //最高位
bcd_fadd instance_high(.a(a[4*i+3 : 4*i]), .b(b[4*i+3 : 4*i]), .cin(io[i-1]), .cout(cout), .sum(sum[4*i+3 : 4*i]));
else
bcd_fadd instance_mid (.a(a[4*i+3 : 4*i]), .b(b[4*i+3 : 4*i]), .cin(io[i-1]), .cout(io[i]), .sum(sum[4*i+3 : 4*i]));
end
endgenerate

endmodule

Warning

  • Warning (10230): Verilog HDL assignment warning at tb_modules.sv(8): truncated value with size 32 to match size of target (4)

Truncating values occur when the right side of an assignment is wider than the left side and the upper bits are cut off. This can indicate a bug if there is a truncation you didn’t expect, so check these carefully. The most common case where this isn’t a bug is when you’re using literals without a width (32 bits is implied), e.g., using assign a[1:0] = 1; instead of assign a[1:0] = 2’d1;.