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
// 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

posted on 2011-04-08 11:45  齐威王  阅读(1077)  评论(0编辑  收藏  举报

导航