Verilog counter does not trigger for different clock signals - verilog

I'm trying to write a counter that simply tracks the positive edge of a clock and increments a variable when it does. The caveat is this circuit must switch between different clock sources. The counter and clock multiplexer function as intended for the default clock in simulation, but the counter does not seem to be seeing the positive edges of the second clock signal. I've tested the multiplexer on its own, and it passes the clock signal through correctly. Any thoughts?
The top module:
module hw1_top(reset, updown, inp, clkSwitch, Clk100MHz, testClock2, out);
input reset, updown, Clk100MHz, testClock2;
input [15:0] inp;
input [3:0] clkSwitch;
output [15:0] out;
wire muxtoclk;
ClockMux mux(
.c1(Clk100MHz),
.c2(testClock2),
.switch(clkSwitch),
.cOut(muxtoclk)
);
UDCounter counter(
.RST(reset),
.UD(updown),
.INP(inp),
.CLK(muxtoclk),
.OUT(out)
);
endmodule
Counter:
module UDCounter(RST, UD, INP, CLK, OUT);
input RST, UD, CLK; //1 bit inputs
input [15:0] INP; //16 bit input
output reg [15:0] OUT; //16 bit output, must be reg for sequential
initial
OUT <= INP; //when we start, counter initializes to whatever the input is
always#(posedge CLK or posedge RST) //on every positive edge of the clock cycle, or if reset is triggered...
if(RST == 1'b1) //if reset is high, set counter back to the initial input
OUT <= INP;
else //if reset isn't triggered...
if(UD == 1'b0) //if up/down is in up position, count up
begin
OUT <= OUT + 1;
end
else //if in down, count down
begin
OUT <= OUT -1;
end
endmodule
Multiplexer:
module ClockMux(c1,c2,switch,cOut);switch,cOut);
input c1,c2;
input [3:0] switch;
output reg cOut;
always#(switch,c1,c2) //updates whenever the switch or clock changes
case(switch)
4'b0000: cOut <= c1;
4'b0001: cOut <= c2;
endcase
endmodule
Top level testbench and waveform:
module hw1_top_tb();
reg reset, updown, Clk100MHz, testClock2;
reg [15:0] inp;
wire [15:0] out;
reg [3:0] switchValue;
hw1_top topmod(
.reset(reset),
.updown(updown),
.inp(inp),
.clkSwitch(switchValue),
.Clk100MHz(Clk100MHz),
.out(out)
);
initial Clk100MHz = 0;
always #5 Clk100MHz = ~Clk100MHz;
initial testClock2 = 0;
always #3 testClock2 = ~testClock2;
initial begin
reset = 0; updown = 0; inp = 16'b0; switchValue = 4'b0000;
#10;
reset = 1; updown = 0; inp = 16'b0; switchValue = 4'b0000;
#10; //toggles the reset briefly to clear dc's
reset = 0; updown = 0; inp = 16'b0; switchValue = 4'b0000;
#40;
reset = 1; updown = 0; inp = 16'b0; switchValue = 4'b0001; //counter is not listening here
#10;
reset = 0; updown = 0; inp = 16'b0; switchValue = 4'b0001; //counter is not listening here
#23;
reset = 1; updown = 0; inp = 16'b0; switchValue = 4'b0000; //when we switch back, it's doing great
#13;
reset = 0; updown = 0; inp = 16'b0; switchValue = 4'b0000;
#23;
$finish;
end
endmodule

You never connected testClock2 in your instantiation topmod of hw1_top:
hw1_top topmod(
.reset(reset),
.updown(updown),
.inp(inp),
.clkSwitch(switchValue),
.Clk100MHz(Clk100MHz),
.testClock2(testClock2), // this is missing
.out(out)
);

Related

UART Transmit and receive data does not start (Vivado)

I can't figure out why is it that when I set the clock frequency from 50MHz to 100MHz, by changing the clk period to 5 in the testbench, my output transmit and receive data stays at 0. Can anyone enlighten me on this? I need my clock frequency to be 100MHz. Your help will be much appreciated.
Testbench
`timescale 1ns / 1ps
module uart_tx_test();
parameter periodCLK_2 = 5;
parameter perioddump = 10;
parameter delay = 1;
parameter delay_in = 2;
reg CLK_TB = 0 ;
reg RSTN ;
reg [7:0] data = 0;
reg clk = 0;
reg enable = 0;
wire tx_busy;
wire rdy;
wire [7:0] rxdata;
wire loopback;
reg rdy_clr = 0;
uart test_uart(.din(data),
.wr_en(enable),
.clk_50m(clk),
.tx(loopback),
.tx_busy(tx_busy),
.rx(loopback),
.rdy(rdy),
.rdy_clr(rdy_clr),
.dout(rxdata));
initial begin
// $dumpfile("uart.vcd");
$dumpvars(0, uart_tx_test);
enable <= 1'b1;
#2 enable <= 1'b0;
end
always begin
#5 clk = ~clk; //I set period to 5; period was 1 previously.
end
always #(posedge rdy) begin
#2 rdy_clr <= 1;
#2 rdy_clr <= 0;
if (rxdata != data) begin
$display("FAIL: rx data %x does not match tx %x", rxdata, data);
$finish;
end else begin
if (rxdata == 8'hff) begin
$display("SUCCESS: all bytes verified");
$finish;
end
data <= data + 1'b1;
enable <= 1'b1;
#2 enable <= 1'b0;
end
end
endmodule
Design Sources
module uart(
input wire [7:0] din,
input wire wr_en,
input wire clk_50m,
output wire tx,
output wire tx_busy,
input wire rx,
input wire rdy_clr,
output wire rdy,
output wire [7:0] dout
);
wire rxclk_en, txclk_en;
baud_rate_gen uart_baud(
.clk_50m(clk_50m),
.rxclk_en(rxclk_en),
.txclk_en(txclk_en)
);
transmitter uart_tx(
.tx(tx),
.din(din),
.clk_50m(clk_50m),
.clken(txclk_en),
.wr_en(wr_en),
.tx_busy(tx_busy)
);
receiver uart_rx(
.rx(rx),
.data(dout),
.clk_50m(clk_50m),
.clken(rxclk_en),
.rdy(rdy),
.rdy_clr(rdy_clr)
);
endmodule
/*
* Hacky baud rate generator to divide a 50MHz clock into a 9600 baud
* rx/tx pair where the rx clcken oversamples by 16x.
*/
module baud_rate_gen(input wire clk_50m,
output wire rxclk_en,
output wire txclk_en);
parameter RX_ACC_MAX = 100000000 / (9600 * 16);
parameter TX_ACC_MAX = 100000000 / 9600;
parameter RX_ACC_WIDTH = $clog2(RX_ACC_MAX);
parameter TX_ACC_WIDTH = $clog2(TX_ACC_MAX);
reg [RX_ACC_WIDTH - 1:0] rx_acc = 0;
reg [TX_ACC_WIDTH - 1:0] tx_acc = 0;
assign rxclk_en = (rx_acc == 5'd0);
assign txclk_en = (tx_acc == 9'd0);
always #(posedge clk_50m) begin
if (rx_acc == RX_ACC_MAX[RX_ACC_WIDTH - 1:0])
rx_acc <= 0;
else
rx_acc <= rx_acc + 5'b1;
end
always #(posedge clk_50m) begin
if (tx_acc == TX_ACC_MAX[TX_ACC_WIDTH - 1:0])
tx_acc <= 0;
else
tx_acc <= tx_acc + 9'b1;
end
endmodule
module transmitter(
input wire [7:0] din,
input wire wr_en,
input wire clk_50m,
input wire clken,
output reg tx,
output wire tx_busy
);
initial begin
tx = 1'b1;
end
parameter STATE_IDLE = 2'b00;
parameter STATE_START = 2'b01;
parameter STATE_DATA = 2'b10;
parameter STATE_STOP = 2'b11;
reg [7:0] data = 8'h00;
reg [2:0] bitpos = 3'h0;
reg [1:0] state = STATE_IDLE;
always #(posedge clk_50m) begin
case (state)
STATE_IDLE: begin
if (wr_en) begin
state <= STATE_START;
data <= din;
bitpos <= 3'h0;
end
end
STATE_START: begin
if (clken) begin
tx <= 1'b0;
state <= STATE_DATA;
end
end
STATE_DATA: begin
if (clken) begin
if (bitpos == 3'h7)
state <= STATE_STOP;
else
bitpos <= bitpos + 3'h1;
tx <= data[bitpos];
end
end
STATE_STOP: begin
if (clken) begin
tx <= 1'b1;
state <= STATE_IDLE;
end
end
default: begin
tx <= 1'b1;
state <= STATE_IDLE;
end
endcase
end
assign tx_busy = (state != STATE_IDLE);
endmodule
module receiver(
input wire rx,
input wire rdy_clr,
input wire clk_50m,
input wire clken,
output reg rdy,
output reg [7:0] data
);
initial begin
rdy = 0;
data = 8'b0;
end
parameter RX_STATE_START = 2'b00;
parameter RX_STATE_DATA = 2'b01;
parameter RX_STATE_STOP = 2'b10;
reg [1:0] state = RX_STATE_START;
reg [3:0] sample = 0;
reg [3:0] bitpos = 0;
reg [7:0] scratch = 8'b0;
always #(posedge clk_50m) begin
if (rdy_clr)
rdy <= 0;
if (clken) begin
case (state)
RX_STATE_START: begin
/*
* Start counting from the first low sample, once we've
* sampled a full bit, start collecting data bits.
*/
if (!rx || sample != 0)
sample <= sample + 4'b1;
if (sample == 15) begin
state <= RX_STATE_DATA;
bitpos <= 0;
sample <= 0;
scratch <= 0;
end
end
RX_STATE_DATA: begin
sample <= sample + 4'b1;
if (sample == 4'h8) begin
scratch[bitpos[2:0]] <= rx;
bitpos <= bitpos + 4'b1;
end
if (bitpos == 8 && sample == 15)
state <= RX_STATE_STOP;
end
RX_STATE_STOP: begin
/*
* The baud clock may not be running at exactly the
* same rate as the transmitter. If we thing that
* we're at least half way into the stop bit, allow
* transition into handling the next start bit.
*/
if (sample == 15 || (sample >= 8 && !rx)) begin
state <= RX_STATE_START;
data <= scratch;
rdy <= 1'b1;
sample <= 0;
end else begin
sample <= sample + 4'b1;
end
end
default: begin
state <= RX_STATE_START;
end
endcase
end
end
endmodule
You need to scale all your other delays accordingly. Change all your #2 to #10, then you will see the SUCCESS: all bytes verified message.
With your original clock delay of #1, your other input signal pulses (enable and rdy_clr) were wide enough for your uart design module to sample properly. For example, on the 1st posedge of clk, your design properly sampled the enable input as 1, which started the TX state machine.
You increased the clock period by a factor of 5 when you changed the delay from #1 to #5. However, your enable pulse stayed the same width as before, which means that the design sampled enable as 0, not 1. So your TX state machine stayed in the IDLE state. By changing the enable delay from #2 to #10, you are able to properly sample enable as 1.
You can easily prove this to yourself by dumping a VCD file, and viewing the waveforms inside the design.
You could replace the numeric delays with a parameter to make it easier to change to different frequencies.
Note: You stated the clk delay was originally #1. This gives the clk signal a period of 2ns, which is 500MHz, not 50MHz.

Why doesn't the up/down counter count down?

I was doing the Logic Design assignment, and I found some problems I can't solve.
I need to design a 6-bit counter, and this counter needs to count with two functions, for up and down respectively.
I have done the up part and down part, but when I run the simulation, the counting down part doesn't work correctly.
The function for counting down: the next a = a - 2^n, where n = 0, 1, 2, 3... eg. a1 = 63, a2 = 63 - 1 = 62, a3 = 62 - 2 = 60, a4 = 56...
But the simulation with my program, it becomes 63, 62, 61(63 - 2), 59(63 - 4)...
By the way, this assignment has a reset feature.
However, my program won't keep counting after being reset.
It should back to zero and continue counting theoretically.
The following is my code:
`timescale 1ns/100ps
module lab2_1(
input clk,
input rst,
output reg [5:0] out
);
reg [5:0] cnt;
wire [5:0] cnt_next;
reg updown;
wire [5:0] out_next;
initial begin
out = 0;
cnt = 1;
updown = 1;
end
assign cnt_next = (out == 6'b111111) ? 0 : cnt + 1;
assign out_next = out - (2**cnt);
always #(*) begin
if(out == 6'b111111)begin
updown = 0;
end
if(out == 6'b000000)begin
updown = 1;
end
if(rst == 1) begin
out = 0;
updown = 1;
cnt = 0;
end
end
always #(posedge clk, posedge rst) begin
if(updown == 1)begin
if(out > cnt)begin
out <= out - cnt;
end
else
out <= out + cnt;
end
else begin
out <= out_next;
end
cnt <= cnt_next;
end
endmodule
The testbench just monitors the output and drives the inpupts.
`timescale 1ns/100ps
module lab2_1_t;
wire [5:0] out;
reg clk;
reg rst;
lab2_1 v(clk, rst, out);
initial begin
clk = 0;
rst = 0;
$monitor($time,":clk = %b, rst = %b, out = %d", clk, rst, out);
end
always #10 clk = ~clk;
always #10000 rst = ~rst;
endmodule
You should not make assignments to the same signal (such as cnt) from multiple blocks. You can assign to cnt from a single always block. I don't think you need both out and cnt.
Here is a simplified version which automatically switches between up and down:
module lab2_1(
input clk,
input rst,
output reg [5:0] cnt
);
reg updown;
always #(posedge clk, posedge rst) begin
if (rst) begin
updown <= 1;
end else if (cnt == 6'b111110) begin
updown <= 0;
end else if (cnt == 6'b000001) begin
updown <= 1;
end
end
always #(posedge clk, posedge rst) begin
if (rst) begin
cnt <= 0;
end else if (updown) begin
cnt <= cnt + 1;
end else begin
cnt <= cnt - 1;
end
end
endmodule
The code shows a more typical use of the reset signal in the sequential always block. See also for more examples.
Here is a modified testbench where the reset is asserted at time 0, then released after a couple clock cycles. At the end, it asserts reset again so you can see that the counter goes to 0.
module lab2_1_t;
wire [5:0] out;
reg clk;
reg rst;
lab2_1 v(clk, rst, out);
initial begin
$monitor($time,":clk = %b, rst = %b, out = %d", clk, rst, out);
clk = 0;
rst = 1;
#40 rst = 0;
#10000 rst = 1;
#1000 $finish;
end
always #10 clk = ~clk;
endmodule

Verilog accumulation code error

I am having a problem with accumulator code in Verilog. I simply generate pseudo random signals. Then, change the random signal level -1 to 1 from 0 to 1 so it is signed. Later, obtained 'acmin'. In this point, I need to accumulate 'acmin' signals. Debugger doesn't give me any error but I can't see any result. Can you help me to find problem?
module lfsr(clk, rst, seed, load, R, acc);
input [3:0] R;
input [26:0] seed;
input load;
input rst;
input clk;
reg [3:0]q;
wire [3:0] S;
wire overflow;
wire [3:0] acmin ;
wire [26:0] state_out;
wire [26:0] state_in;
output [7:0] acc;
reg [7:0] acc;
flipflop F[26:0] (state_out, clk, rst, state_in);
mux M1[26:0] (state_in, load, seed, {state_out[25],state_out[24],state_out[23],state_out[22],state_out[21],state_out[20],state_out[19],state_out[18],state_out[17],state_out[16],state_out[15],state_out[14],state_out[13],state_out[12],state_out[11],state_out[10],state_out[9],state_out[8],state_out[7],state_out[6],state_out[5],state_out[4],state_out[3],state_out[2], state_out[1], state_out[0], nextbit});
xor G1(nextbit, state_out[5], state_out[2], state_out[1], state_out[26]);
// Pseudorandom generator
always#(clk) begin
if (state_out[26]==0)
q=4'b1111; // 0 to -1
else
q=4'b0001; //1 to 1
end
assign acmin= R*q; // accumulator input
always#(clk) begin
if(rst)
acc = 8'b00000000;
else
acc = acc + acmin;
end
endmodule
Test bench;
module lfsrtst;
reg [3:0] R;
reg clk;
reg rst;
reg [26:0] seed;
reg load;
wire [7:0] acc;
lfsr lfsr(clk, rst, seed, load, R, acc);
initial
begin
clk = 0;
load = 0;
seed = 0;
rst = 0;
R=0;
#10 rst = 1;
#10 rst = 0;
#50 R = 4'b0111;
#50 R = 4'b0010;
#100 R = 4'b1111;
#50 R = 4'b1011;
#150 R = 4'b1101;
#50 R = 4'b1000;
end
// drive clock
always
#50 clk = !clk;
// program lfsr
initial begin
#100 seed = 27'b000000110000011000001000001;
load = 1;
#100 load = 0;
#1400 $stop;
end
endmodule
I have 'acmin' as I desired. I want to accumulate 'acmin' variable every time the edge of the clock rises and falls. However, 'acc' results nothing so what is the error?
Thanks.
The main problem that I see is that you have a synchronous reset:
always#(clk) begin
if(rst)
acc = 8'b00000000;
else
acc = acc + acmin;
end
But in your testbench you only strobe the reset for #20
#10 rst = 1;
#10 rst = 0;
This is too short, and the reset is never detected.
If you make these delays longer, then the problem should be fixed.
#100 rst = 1;
#100 rst = 0;
// then later
// program lfsr
initial begin
# also delay this so that it comes after the reset
#300 seed = 27'b000000110000011000001000001;
Alternatively you could make the reset asynchronous.
always#(clk or posedge rst) begin
I would try imply a flip-flop here by adding the posedge and converting to '<='
always#(posedge clk) begin
if(rst)
acc <= 8'b00000000;
else
acc <= acc + acmin;
end

Not getting simulated output for an error free verilog code

I'm somewhat new to verilog. So this question might be very simple.
I'm trying to simulate an finite state machine using verilog.
Brief description:
There are three states: 0,1 & 2. By default, State is 0.
The state changes to 1 only if input is 01.
The state changes to 2 only if input is 10.
The state changes back to 0 only if input is 00.
The code is getting simulated successfully, but I.m getting no output. Please help me with the problem.
Code: (State.v)
module State(
input clk,
input reset,
input [3:0] in,
output [3:0] out,
output [3:0] state
);
wire clk,reset;
wire [3:0] in;
reg [3:0] out;
reg [3:0] state;
always #(posedge clk or posedge reset)
begin
if (reset == 1)
begin
state = 0;
end
else
begin
case (state)
0: if(in == 2'b01)
state = 1;
else
state = 0;
1: if(in == 2'b10)
state = 2;
else
state = 1;
2: if(in == 2'b00)
state = 0;
else
state = 2;
default: state = 0;
endcase
end
end
always #(*)
begin
case (state)
0: out = 2'b00;
1: out = 2'b01;
2: out = 2'b10;
default: out = 2'b00;
endcase
end
endmodule
Testbench: (StateTestBench.v)
module StateTestBench;
// Inputs
reg clk;
reg reset;
reg [3:0] in;
// Outputs
reg [3:0] out;
reg [3:0] state;
always
begin
#1 clk = !clk;
end
// Instantiate the Unit Under Test (UUT)
State uut (
.clk(clk),
.reset(reset),
.in(in),
.out(out),
.state(state)
);
initial begin
// Initialize Inputs
clk = 0;
reset = 0;
#1 reset = 1;
#10 reset = 0;
#5 in = 2'b00;
#10 in = 2'b01;
#10 in = 2'b10;
end
endmodule
I guess you simulate state.v instead of StateTestBench.v. Because your testbench has a bug! Outputs out and state MUST be wires.

Generating unsigned number for booth multiplier

For an academic excercise, I have implemented a 32-bit Karatsuba multiplier which takes 17 cycles to run by doing parallel multiplication of 16 bits each and shifting them accordingly.
I am getting an issue where the partial products need to be unsigned, but booth multiplier is generating signed partial product for me, regardless of the input type I give, because of which I get incorrect partial products. How can I solve this?
For eg. my two signed inputs are 0xA000_000A and 0x000A_A000. So the first partial product of A000 * 000A should be 64000 but I get 0xFFFC4000 (FFFF_A000 * 0000_000A). I have shared my code here for the booth mult and its testbench.
module booth_multiplier
(
input logic clk,
input logic rst,
input logic valid,
input logic signed [15:0] Mul_X,
input logic signed [15:0] Mul_Y,
output logic signed [31:0] product,
output logic result_ready
);
logic unsigned Q_1;
bit [4:0] count;
logic signed [15:0] multiplier;
logic signed [15:0] multiplicand;
logic [15:0] A, temp_A;
logic signed [32:0] partial_product;
logic signed [32:0] partial_multiplier;
typedef enum {IDLE=0, OPERATE} fsm;
fsm state, next_state;
parameter ADD = 2'b01, SUB = 2'b10;
//assign product = multiplier[16:1];
always#(posedge clk or negedge rst)
begin
if(~rst)
begin
count <= 0;
state <= IDLE;
multiplier <= 0;
multiplicand <= 0;
end
else begin
count <= count+1;
state <= next_state;
end
end
always#(*)
begin
case(state)
IDLE : begin
Q_1 = 0;
A = 0;
count = 0;
product = 0;
temp_A = 0;
result_ready = 0;
if(valid) begin
multiplicand = Mul_X;
multiplier = Mul_Y;
partial_product = {A, multiplier, Q_1};
partial_multiplier = 0;
next_state = OPERATE;
end
end
OPERATE: begin
case(partial_product[1:0])
ADD: begin
temp_A = A + multiplicand;
multiplier = partial_product[16:1];
partial_multiplier = {temp_A, multiplier, Q_1};
partial_product = partial_multiplier >>> 1;
Q_1 = partial_product[0];
A = partial_product[32:17];
end
SUB: begin
temp_A = A - multiplicand;
multiplier = partial_product[16:1];
partial_multiplier = {temp_A, multiplier, Q_1};
partial_product = partial_multiplier >>> 1;
Q_1 = partial_product[0];
A = partial_product[32:17];
end
default: begin
temp_A = A;
multiplier = partial_product[16:1];
partial_multiplier = {temp_A, multiplier, Q_1};
partial_product = partial_multiplier >>> 1;
Q_1 = multiplier[0];
A = partial_product[32:17];
end
endcase
if(count == 16) begin
next_state = IDLE;
product = partial_product >> 1;
result_ready = 1;
end
else next_state = OPERATE;
end
endcase
end
endmodule
This I am using to do 4 parallel multiplications in
module fast_multiplier
(
input logic clk,
input logic rst,
input valid,
input logic signed [31:0] multiplicand,
input logic signed [31:0] multiplier,
output logic signed [63:0] product,
output logic ready);
logic [15:0] X1;
logic [15:0] Y1;
logic [15:0] Xr;
logic [15:0] Yr;
logic [31:0] X1_Yr;
logic [31:0] Xr_Yr;
logic [31:0] X1_Y1;
logic [31:0] Xr_Y1;
logic ready1, ready2, ready3, ready4;
assign X1 = multiplicand[31:16];
assign Y1 = multiplier[31:16];
assign Xr = multiplicand[15:0];
assign Yr = multiplier[15:0];
booth_multiplier X1Y1
(
.clk(clk),
.rst(rst),
.valid(valid),
.Mul_X(X1),
.Mul_Y(Y1),
.product(X1_Y1),
.result_ready(ready1));
booth_multiplier X1Yr
(
.clk(clk),
.rst(rst),
.valid(valid),
.Mul_X(X1),
.Mul_Y(Yr),
.product(X1_Yr),
.result_ready(ready2));
booth_multiplier XrY1
(
.clk(clk),
.rst(rst),
.valid(valid),
.Mul_X(Xr),
.Mul_Y(Y1),
.product(Xr_Y1),
.result_ready(ready3));
booth_multiplier XrYr
(
.clk(clk),
.rst(rst),
.valid(valid),
.Mul_X(Xr),
.Mul_Y(Yr),
.product(Xr_Yr),
.result_ready(ready4));
always#(posedge clk or negedge rst)
begin
if(~rst)
begin
product <= 0;
ready <= 0;
X1_Yr <= 0;
X1_Y1 <= 0;
Xr_Yr <= 0;
Xr_Y1 <= 0;
end
else begin
product <= ({32'b0,X1_Y1} << 32) + (({32'b0,X1_Yr} + {32'b0,Xr_Y1}) << 16) + {32'b0,Xr_Yr};
ready <= ready1 & ready2 & ready3 & ready4;
end
end
endmodule
Also, sharing the testbench,
module top_booth_multiplier ();
logic clk;
logic rst;
logic valid;
logic signed [31:0] multiplicand;
logic signed [31:0] multiplier;
logic signed [63:0] product;
logic ready;
fast_multiplier booth (.*);
initial
begin
clk = 0;
forever #10 clk = ~clk;
end
initial
begin
rst = 0;
#7 rst = 1;
#(posedge clk) valid <= 1;
multiplier = 32'hA000000A;
multiplicand = 32'h000AA000;
#(posedge clk) valid <= 0;
while(ready == 0)
begin
#(posedge clk);
end
repeat (20) #(posedge clk);
$finish;
end
endmodule
You need to consider "signed" inputs in booth multiplier ONLY for X1Y1 instance. All other instances MUST use "unsigned" inputs. This change should help!

Resources