endmodule
module test_Multiplier_RR_ASM ();
parameter word_size = 4;
wire [2*word_size: 0] product;
//wire Done;
initial #80000 $finish; // Timeout
always @ (posedge clock) // Compare product with expected value
if (Start) begin
#5 expected_value <= 0;
expected_value <= word2 * word1;
// expected_value <= word2 * word1 + 1; // Use to check error detection
code_error <= 0;
end
end
initial begin
for (word1 = 0; word1 <= 15; word1 = word1 +1) begin
for (word2 = 0; word2 <= 15; word2 = word2 +1) begin
Start <= 0; #40 Start <= 1;
Problem 10-7
The code for the implicit state machine Multiplier_IMP_1 corresponds to the ASM chart
shown in the next column. The multiple states of the for loop are not all shown. For the
module Multiplier_IMP_1_Alternative #(parameter L_word = 4)(
output [2*L_word -1: 0] product,
output Ready, Done,
input [L_word -1: 0] word1, word2,
input Start, clock, reset
always
@ (posedge clock, posedge reset) begin: Main_Block
if (reset == 1’b1) begin Set_Regs; disable Main_Block; end
else if (Start != 1) begin: Idling
product <= 0; Ready <= 1;
end // Idling
end
@ (posedge clock, posedge reset)
if (reset == 1’b1) begin Set_Regs; disable Main_Block; end
else begin // not reset
if (m0_1) Add_shift;
else Shift;
task Set_Regs;
begin
Ready <= 1; Done <= 1;
end
endtask
task Shift;
begin
multiplier <= multiplier >> 1;
multiplicand <= multiplicand << 1;
end
endtask
endmodule
// Exhaustive Testbench
reg [2*L_word-1: 0] expected_value;
wire code_error;
//initial #1600 $finish;
initial #80000 $finish; // Timeout
assign code_error = ((!Start) && Ready && (M1.M2.Done == 1))? |(expected_value ^ product) :
0;
join
initial begin #15400 reset =1; # 20 reset = 0; end
initial begin #28800 reset =1; # 60 reset = 0; end
//initial begin #29850 Start = 1; #800 Start = 0; end
//initial begin #321 Start = 1; #100 Start = 0; end
initial begin clock <= 0; forever #10 clock <= ~clock; end
initial begin // Exhaustive patterns
#2 reset = 1;
endmodule
Problem 10-21
The machine is made more efficient by detecting whether word1 or word2 is 0 or 1. The
result is used to abort the multiplication process, as shown in the STG below.
module Multiplier_Radix_4_STG_1 #(parameter L_word = 8) (
output [2*L_word -1: 0] product,
module Controller_Radix_4_STG_0 #(parameter L_word = 8)(
output reg Load_words, Shift_1, Shift_2, Add, Sub,
output Ready,
input [2: 0] BPEB,
input Start, Abort, clock, reset
);
always @ (state, Start, Abort, BPEB) begin // Next state and control logic
Load_words = 0; Shift_1 = 0; Shift_2 = 0; Add = 0; Sub = 0;
case (state)
S_idle: if (Start) begin Load_words = 1; next_state = S_1; end
else next_state = S_idle;
S_1: if (Abort) next_state = S_idle);
else case (BPEB)
0: begin Shift_2 = 1; next_state = S_5; end
2: begin Add = 1; next_state = S_2; end
0, 7: begin Shift_2 = 1; next_state = S_13; end
1, 2: begin Add = 1; next_state = S_10; end
3, 4: begin Shift_1 = 1; next_state = S_11; end
5, 6: begin Sub = 1; next_state = S_10; end
endcase
S_14: begin Shift_2 = 1; next_state = S_17; end
S_15: begin if (BPEB[1: 0] == 2’b01) Add = 1;
else Sub = 1; next_state = S_16; end
S_16: begin Shift_1 = 1; next_state = S_17; end
S_17: if (Start) begin Load_words = 1; next_state = S_1; end
else next_state = S_17;
default: next_state = S_idle;
endcase
end
endmodule
1);
// Register/Datapath Operations
always @ (posedge clock, posedge reset)
if (reset) begin
multiplier <= 0; m0_del <= 0; multiplicand <= 0; product <= 0;
end
else begin
if (Abort) begin
if (multiplier == 0) || (multiplicand == 0) product <= 0;
else if (muliplier) == 1) product <= multiplicand;
else f (multipilcand == 1) product <= multiplier);
end
if (Load_words) begin
m0_del <= 0;
if (word1[L_word -1] == 0) multiplicand <= word1;
else multiplicand <= {‘All_Ones, word1[L_word -1: 0]};
Problem 10-24
A strategy that will reduce the simulation activity of remainder is to make remainder a
registered output and update remainder when the process of forming quotient is
complete. Making Error a registered output does not affect simulation activity because
Modifications to Divider_STG_0 are shown below.
module Divider_STG_0 #(parameter L_divn = 8, L_divr = 4)(
output [L_divn -1: 0] quotient,
/* Includes checks for a divide by zero, subtracts the divisor from the dividend until the dividend is
less than the divisor, and counts the number of subtractions performed. The length of divisor
must not exceed the length of dividend .
*/
Control_Unit M0 (Ready, Error, Load_words, Subtract, Start, GTE, w1_is_0, w2_is_0, clock,
reset);
Datapath_Unit M1 (quotient, remainder, GTE, w1_is_0, w2_is_0, word1, word2, Load_words,
Subtract, clock, reset);
endmodule
end
always @ (posedge clock, posedge reset)
if (reset) state <= S_idle; else state <= next_state;
S_1: if (GTE) begin next_state = S_2; Subtract = 1; end
else next_state = S_3;
S_2: if (GTE) begin next_state = S_2; Subtract = 1; end
else next_state = S_3;
module Datapath_Unit #(parameter L_divn = 8, L_divr = 4)(
output reg [L_divn -1: 0] quotient,
// output [L_divn -1: 0] remainder, // Note modification
output reg [L_divn -1: 0] remainder,
output GTE, w1_is_0, w2_is_0,
input [L_divn -1: 0] word1, // Datapath for dividend
input [L_divr -1: 0] word2, // Datapath for divisor
input Load_words, Subtract, clock, reset
if (reset) begin divisor <= 0; dividend <= 0; quotient <= 0;
remainder <= 0; // Note modification
end
else if (Load_words == 1) begin
dividend <= word1;
Problem 10-25
Modify the controller to make a transition from S_Err to S_1, as shown in the STG
below:
/* Includes checks for a divide by zero, subtracts the divisor from the dividend until the dividend is
less than the divisor, and counts the number of subtractions performed. The length of divisor
must not exceed the length of dividend .
*/
Control_Unit M0 (Ready, Error, Load_words, Subtract, Start, GTE, w1_is_0, w2_is_0, clock,
reset);
Datapath_Unit M1 (quotient, remainder, GTE, w1_is_0, w2_is_0, word1, word2, Load_words,
Subtract, clock, reset);
assign Ready = ((state == S_idle) && !reset) || (state == S_3);
assign Error = (state == S_Err);
S_idle: case (Start)
0: next_state = S_idle;
1: if (w2_is_0) next_state = S_Err;
else if (!w1_is_0) begin next_state = S_1; Load_words = 1; end
else next_state = S_3;
endcase
else begin next_state = S_1; Load_words = 1; end
endcase
//S_Err: next_state = S_Err; Note modification
S_Err: case (Start)
0: next_state = S_Err;
1: if (w2_is_0) next_state = S_Err;
else if (!w1_is_0) begin next_state = S_1; Load_words = 1; end
else next_state = S_3;
endcase
default: next_state = S_Err;
endcase
end
assign GTE = (dividend >= divisor); // Comparator
assign w1_is_0 = (word1 == 0);
assign w2_is_0 = (word2 == 0);
assign remainder = dividend;
always @(posedge clock, posedge reset) begin // Register/Datapath Operations
Problem 10-26
Modify the controller to form Ready as a Mealy output, as shown below.
module Divider_Prob_10_26 #(parameter L_divn = 8, L_divr = 4)(
output [L_divn -1: 0] quotient,
output [L_divn -1: 0] remainder,
output Ready, Error,
input [L_divn -1: 0] word1, // Datapath for dividend
input [L_divr -1: 0] word2, // Datapath for divisor
input Start, clock, reset
);
always @ (posedge clock, posedge reset)
if (reset) state <= S_idle; else state <= next_state;
always @ (state, Start, GTE, w1_is_0, w2_is_0) begin
Load_words = 0; Subtract = 0; next_state = S_Err; // Default values
case (state)
S_idle: case (Start)
0: next_state = S_idle;
1: if (w2_is_0) next_state = S_Err;
else if (!w1_is_0) begin next_state = S_1; Load_words = 1; end
else next_state = S_3;
S_Err: next_state = S_Err;
default: next_state = S_Err;
endcase
end
endmodule
assign remainder = dividend;
always @(posedge clock, posedge reset) begin // Register/Datapath Operations
if (reset) begin divisor <= 0; dividend <= 0; quotient <= 0; end
else if (Load_words == 1) begin