It has something to do with the thread issue mostly, may be multiple threads are trying to drive ack rather than just one, is there any other solution to this rather than automatic
?
class four_phase_handshake;
semaphore ack_semaphore;
reg req_accepted = 0;
reg req_deasserted = 0;
reg ack = 0;
logic clocking_cb; // Input for the clock signal
logic req; // Input for the request signal
// Constructor
function new();
ack_semaphore = new(1); // Initialize semaphore with 1 token
endfunction
task main();
forever begin
fork
begin
// Simulated thread for capturing req
// This thread can be customized as needed
@(posedge clocking_cb);
$display("Thread 1: Capturing req at time %0t", $time);
end
begin
// Main handshake logic
@(posedge clocking_cb);
ack_semaphore.get(); // Acquire semaphore
if (req && !req_accepted) begin
$display("\n=== 1 req_accepted=%d req_deasserted=%d at time = %t ===", req_accepted, req_deasserted, $time);
req_accepted <= 1;
ack <= 1;
end
else if (req && req_accepted) begin
$display("\n=== 2 req_accepted=%d req_deasserted=%d at time = %t ===", req_accepted, req_deasserted, $time);
ack <= 1;
end
else if (!req && req_accepted) begin
$display("\n=== 3 req_accepted=%d req_deasserted=%d at time = %t ===", req_accepted, req_deasserted, $time);
req_deasserted <= 1;
req_accepted <= 0;
ack <= 1;
end
else if (req_deasserted) begin
$display("\n=== 4 req_accepted=%d req_deasserted=%d at time = %t ===", req_accepted, req_deasserted, $time);
ack <= 0;
req_deasserted <= 0;
end
else begin
$display("\n=== 5 req_accepted=%d req_deasserted=%d at time = %t ===", req_accepted, req_deasserted, $time);
ack <= 0;
req_accepted <= 0;
req_deasserted <= 0;
end
ack_semaphore.put(); // Release semaphore
end
begin
// Simulated thread for another task, such as incrementing a variable
// This thread can be customized as needed
@(posedge clocking_cb);
$display("Thread 3: Incrementing variable at time %0t", $time);
end
join_any
end
endtask
WHy do you have a “join_any”?
If this fork ends first, you don’t finish the other 2 fork elements.
begin
// Simulated thread for another task, such as incrementing a variable
// This thread can be customized as needed
@(posedge clocking_cb);
$display("Thread 3: Incrementing variable at time %0t", $time);
end
I see ack <= 1; when
if (req && !req_accepted)
else if (req && req_accepted)
else if (!req && req_accepted)
I see ack <= 0 when else if (req_deasserted)
Question: what happens in the 1st 3 cases if is (req_deasserted)
I don’t know your design or rquirements, but if you are designing a verification environment for the RTL, maybe something is wrong with your logic.
You need to analyze the logic; maybe you have some sort of latchup situation or incorrect RTL. discuss it with a colleague. Do a step-by-step trace.
Best wishes