module LONGMULT8b8(clk, reset, C, Ready, A, B, Start);
input clk, reset, Start;
output Ready;
input [7:0] A, B;
output [15:0] C;
reg [15:0] RC, RB, RA;
reg Ready;
// Behavioural code:
// while (1)
// {
// wait (Start);
// RA=A;RB=B;RC=0;
// while(RA>0)
// { if odd(RA) RC=RC+RB;
// RA = RA >> 1; RB = RB << 1;
// }
// Ready = 1;
// wait(!Start);
// Ready = 0;
// }
reg xx, yy, qq, pp; // Control and predicate nets
reg [1:0] fc;
reg [3:0] state;
always @(posedge clk) begin
xx = 0; // default settings.
yy = 0;
fc = 0;
// Predicates
pp = (RA!=16'h0); // Work while pp holds
qq = RA[0]; // Odd if qq holds
// Sequencer
if (reset) begin
state <= 0;
Ready <= 0;
end
else case (state)
0: if (Start) begin
xx = 1;
yy = 1;
fc = 2;
state <= 1;
end
1: begin
fc = qq;
if (!pp) state <= 2;
end
2: begin
Ready <= 1;
if (!Start) state <= 3;
end
3: begin
Ready <= 0;
state <= 0;
end
endcase // case (state)
// Datapath
RB <= (yy) ? B: RB<<1;
RA <= (xx) ? A: RA>>1;
RC <= (fc==2) ? 0: (fc==1) ? RC+RB: RC;
end
assign C = RC;
endmodule
Suitable test wrapper:
module SIMSYS();
reg clk, reset, Start;
wire Ready;
wire [7:0] A, B;
wire [15:0] C;
// Reset Generator
initial begin reset = 1; # 55 reset = 0; end
// Clock Generator
initial begin clk = 0; forever #10 clk = !clk; end
// Stimulus
assign A = 6;
assign B = 7;
// Handshake control
always @(posedge clk) Start <= !Ready;
// Console ouput logging:
always @(posedge clk) $display("Ready=%h C=%d");
// Device under test.
LONGMULT8b8 the_mult(clk, reset, C, Ready, A, B, Start);
endmodule // SIMSYS
| 37: (C) 2012-17, DJ Greaves, University of Cambridge, Computer Laboratory. | |