FPGA Prototyping By Verilog Examples第三章
// Listing 3.1
module eq1_always
(
input wire i0, i1,
output reg eq // eq declared as reg
);
// p0 and p1 declared as reg
reg p0, p1;
always @(i0, i1) // i0 an i1 must be in sensitivity list
begin
// the order of statements is important
p0 = ~i0 & ~i1;
p1 = i0 & i1;
eq = p0 | p1;
end
endmodule
// Listing 3.2
module and_block_assign
(
input wire a, b, c,
output reg y
);
always @*
begin
y = a;
y = y & b;
y = y & c;
end
endmodule
// Listing 3.4
module prio_encoder_if
(
input wire [4:1] r,
output reg [2:0] y
);
always @*
if (r[4]==1'b1) // can be written as (r[4])
y = 3'b100;
else if (r[3]==1'b1) // can be written as (r[3])
y = 3'b011;
else if (r[2]==1'b1) // can be written as (r[2])
y = 3'b010;
else if (r[1]==1'b1) // can be written as (r[1])
y = 3'b001;
else
y = 3'b000;
endmodule
![](https://pic002.cnblogs.com/images/2011/128091/2011040811295349.jpg)
// Listing 3.5
module decoder_2_4_if
(
input wire [1:0] a,
input wire en,
output reg [3:0] y
);
always @*
if (en==1'b0) // can be written as (~en)
y = 4'b0000;
else if (a==2'b00)
y = 4'b0001;
else if (a==2'b01)
y = 4'b0010;
else if (a==2'b10)
y = 4'b0100;
else
y = 4'b1000;
endmodule
// Listing 3.6
module decoder_2_4_case
(
input wire [1:0] a,
input wire en,
output reg [3:0] y
);
always @*
case({en,a})
3'b000, 3'b001, 3'b010, 3'b011: y = 4'b0000;
3'b100: y = 4'b0001;
3'b101: y = 4'b0010;
3'b110: y = 4'b0100;
3'b111: y = 4'b1000; // default can also be used
endcase
endmodule
// Listing 3.7
module prio_encoder_case
(
input wire [4:1] r,
output reg [2:0] y
);
always @*
case(r)
4'b1000, 4'b1001, 4'b1010, 4'b1011,
4'b1100, 4'b1101, 4'b1110, 4'b1111:
y = 3'b100;
4'b0100, 4'b0101, 4'b0110, 4'b0111:
y = 3'b011;
4'b0010, 4'b0011:
y = 3'b010;
4'b0001:
y = 3'b001;
4'b0000: // default can also be used
y = 3'b000;
endcase
endmodule
// Listing 3.8
module prio_encoder_casez
(
input wire [4:1] r,
output reg [2:0] y
);
always @*
casez(r)
4'b1???: y = 3'b100;
4'b01??: y = 3'b011;
4'b001?: y = 3'b010;
4'b0001: y = 3'b001;
4'b0000: y = 3'b000; // default can also be used
endcase
endmodule
// Listing 3.10
module adder_carry_local_par
(
input wire [3:0] a, b,
output wire [3:0] sum,
output wire cout // carry-out
);
// constant declaration
localparam N = 4,
N1 = N-1;
// signal declaration
wire [N:0] sum_ext;
//body
assign sum_ext = {1'b0, a} + {1'b0, b};
assign sum = sum_ext[N1:0];
assign cout= sum_ext[N];
endmodule
// Listing 3.11
module adder_carry_para
#(parameter N=4)
(
input wire [N-1:0] a, b,
output wire [N-1:0] sum,
output wire cout // carry-out
);
// constant declaration
localparam N1 = N-1;
// signal declaration
wire [N:0] sum_ext;
//body
assign sum_ext = {1'b0, a} + {1'b0, b};
assign sum = sum_ext[N1:0];
assign cout= sum_ext[N];
endmodule
// Listing 3.13
module adder_carry_95 (a, b, sum, cout);
parameter N = 4; // parameter declared before the port
parameter N1 = N-1; // no localparam in Verilog-1995
input wire [N1:0] a, b;
output wire [N1:0] sum;
output wire cout;
// signal declaration
wire [N:0] sum_ext;
//body
assign sum_ext = {1'b0, a} + {1'b0, b};
assign sum = sum_ext[N1:0];
assign cout= sum_ext[N];
endmodule
Guidelines
Sign-magnitude adder
// Listing 3.16
module sign_mag_add
#(
parameter N=4
)
(
input wire [N-1:0] a, b,
output reg [N-1:0] sum
);
// signal declaration
reg [N-2:0] mag_a, mag_b, mag_sum, max, min;
reg sign_a, sign_b, sign_sum;
//body
always @*
begin
// separate magnitude and sign
mag_a = a[N-2:0];
mag_b = b[N-2:0];
sign_a = a[N-1];
sign_b = b[N-1];
// sort according to magnitude
if (mag_a > mag_b)
begin
max = mag_a;
min = mag_b;
sign_sum = sign_a;
end
else
begin
max = mag_b;
min = mag_a;
sign_sum = sign_b;
end
// add/sub magnitude
if (sign_a==sign_b)
mag_sum = max + min;
else
mag_sum = max - min;
// form output
sum = {sign_sum, mag_sum};
end
endmodule
![](https://pic002.cnblogs.com/images/2011/128091/2011040813205226.jpg)
路漫漫其修远兮,吾将上下而求索