Hi, I am testing apb signals on eda-playground.
module fsm(clk, PSEL, PENABLE, reset, out1, out2);
input clk;
input PSEL;
input PENABLE;
input reset;
output out1;
output out2;
reg [2:0] state;
reg [2:0] next_state;
// State encodings
parameter [2:0]
IDLE = 3'b001,
STATE_1 = 3'b010,
FINAL = 3'b100;
// State machine output
assign out1 = (state == STATE_1);
assign out2 = (state == FINAL);
// State transitions
always @(*) begin // (*) because this state being affect by all others signals
case (state)
IDLE: begin
if (PSEL & ~PENABLE) begin
next_state = STATE_1;
end else begin
next_state = IDLE;
end
end
STATE_1: begin
if (PSEL & PENABLE) begin
next_state = FINAL;
end else begin
next_state = STATE_1;
end
end
FINAL: begin
next_state = IDLE;
end
default: begin
next_state = IDLE;
end
endcase
end
always @(posedge clk or negedge reset) begin
if(~reset) begin
state <= IDLE;
end else begin
state <= next_state;
end
end
endmodule
module test;
reg clk, reset, PSEL, PENABLE;
wire out1, out2;
// Instantiate device under test
fsm DUT(.clk(clk),
.PSEL(PSEL),
.PENABLE(PENABLE),
.reset(reset),
.out1(out1),
.out2(out2));
task toggle_clk;
begin
#10 clk = ~clk;
#10 clk = ~clk;
end
endtask
initial begin
reset = 0;
#10;
@(posedge clk);
reset = 1;
end
initial begin
PSEL = 0;
PENABLE = 0;
//
// #10;
// PSEL = 1;
// #20;
// PENABLE = 1;
// #20;
// PSEL = 0;
// PENABLE = 0;
@(posedge clk);
PSEL = 1;
@(posedge clk);
PENABLE = 1;
@(posedge clk);
PSEL = 0;
PENABLE = 0;
end
initial begin
clk = 0;
$display("Initial out1: %0h, out2: %0h",
out1, out2);
toggle_clk;
$display("IDLE out1: %0h, out2: %0h",
out1, out2);
toggle_clk;
$display("STATE_1 out1: %0h, out2: %0h",
out1, out2);
toggle_clk;
$display("FINAL out1: %0h, out2: %0h",
out1, out2);
toggle_clk;
$display("FINAL out1: %0h, out2: %0h",
out1, out2);
toggle_clk;
$display("IDLE out1: %0h, out2: %0h",
out1, out2);
#1000;
$stop;
end
initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(1, test);
$dumpvars(1, DUT);
end
endmodule
My question is when I try to use @(posedge clk); then state and next_state is not running correctly.
I thought it is a proper way to test APB signal. I do not know why it is wrong.
initial begin
PSEL = 0;
PENABLE = 0;
// #10;
// PSEL = 1;
// #20;
// PENABLE = 1;
// #20;
// PSEL = 0;
// PENABLE = 0;
@(posedge clk);
PSEL = 1;
@(posedge clk);
PENABLE = 1;
@(posedge clk);
PSEL = 0;
PENABLE = 0;
But if I use timing to configure PSEL and PENABLE
initial begin
PSEL = 0;
PENABLE = 0;
#10;
PSEL = 1;
#20;
PENABLE = 1;
#20;
PSEL = 0;
PENABLE = 0;
// @(posedge clk);
// PSEL = 1;
// @(posedge clk);
// PENABLE = 1;
// @(posedge clk);
// PSEL = 0;
// PENABLE = 0;
end
then I can get state signal running after next_state one cycle. That is correct, right?
In this example, I use cadence xcelium 23.09.
Can anybody explain why using @(posedge clk); is not correct? I hope it is not a tool related question. Thank you.