module MULTIPLY_revision
(
input clk, reset, start,
input [7:0] A, B,
output reg done_tick,
output wire [15:0] out
);
localparam [1:0]
idle = 2'b00,
op = 2'b01,
done = 2'b10;
// signal declaration
reg carry, next_carry;
reg [1:0] state, next_state;
reg [15:0] product, next_product;
reg [7:0] ph, pl, next_ph, next_pl;
reg [4:0] counter, next_counter;
/*
initial
begin
state = 0;
next_state = 0;
product = 0;
next_product = 0;
ph = 0;
next_ph = 0;
pl = 0;
next_pl = 0;
counter = 7;
next_counter = 0;
end*/
always @(posedge clk, posedge reset)
if (reset)
begin
next_state = idle;
next_product = 0;
next_ph = 0;
next_pl = 0;
next_counter = 0;
end
else
begin
state <= next_state;
carry <= next_carry;
product <= next_product;
counter <= next_counter;
ph <= next_ph;
pl <= next_pl;
end
// next state logic
always @ *
begin
done_tick = 1'b0;
next_ph = ph;
next_pl = pl;
next_product = product;
next_carry = carry;
next_counter = counter;
next_state = idle;
case(state)
idle:
begin
if(start)
begin
next_state = op;
next_counter = 7;
next_ph = A;
next_product = {8'b0,B};
next_carry = 0;
end
end
op:
begin
if (counter == 0)
begin
next_state = done;
end
else
begin
if(product[0] == 1)
begin
{next_carry,next_product[15:8]} = product[15:8] + ph;
// shift to the right
next_product[15:0] = {carry,product[15:1]};
next_carry = 0;
next_counter = counter - 1;
next_state = op;
end
else
begin
next_product[15:0] = {carry,product[15:1]};
next_carry = 0;
next_counter = counter - 1;
next_state = op;
end
end
end
done:
begin
done_tick = 1'b1;
next_state = idle;
end
default: next_state = idle;
endcase
end
assign out = product;
endmodule