module multiply
(
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;
reg[1:0] state, next_state;
reg [15:0] product;
reg [7:0] ph;
reg [4:0] counter;
always @(posedge clk, posedge reset)
if (reset)
begin
state <= idle;
end
else
begin
state <= next_state;
end
// next state logic
always @ *
begin
next_state = state;
done_tick = 1'b0;
case(state)
idle:
begin
if(start)
begin
product[15:8] = 8'd0;
product[7:0] = B;
ph = A;
counter = 7;
carry = 1'd0;
next_state = op;
end
end
op:
begin
if(product[0] == 1)
begin
{carry,product[15:8]} = product[15:8] + ph;
// shift to the right
product[15:0] = {carry,product[15:1]};
carry = 0;
counter = counter - 1;
end
else
begin
product[15:0] = {carry,product[15:1]};
carry = 0;
counter = counter - 1;
end
if(counter == 0)
begin
next_state = done;
end
end
done:
begin
done_tick = 1'b1;
next_state = idle;
end
default: next_state = idle;
endcase
end
assign out = product;
endmodule