115 lines
2.8 KiB
Systemverilog
115 lines
2.8 KiB
Systemverilog
|
|
// DESCRIPTION: Verilator: FSM coverage supports wide sparse state values
|
||
|
|
//
|
||
|
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||
|
|
// SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||
|
|
// SPDX-License-Identifier: CC0-1.0
|
||
|
|
|
||
|
|
module t (
|
||
|
|
input logic clk
|
||
|
|
);
|
||
|
|
|
||
|
|
typedef enum logic [39:0] {
|
||
|
|
E_S0_IDLE = 40'h0000_0000_01,
|
||
|
|
E_S1_BUSY = 40'h8000_0000_02,
|
||
|
|
E_S2_DONE = 40'hffff_0000_03
|
||
|
|
} enum_state_t;
|
||
|
|
|
||
|
|
localparam logic [47:0] L_S0_IDLE = 48'h0000_0000_0001;
|
||
|
|
localparam logic [47:0] L_S1_BUSY = 48'h8000_0000_0002;
|
||
|
|
localparam logic [47:0] L_S2_DONE = 48'hffff_0000_0003;
|
||
|
|
|
||
|
|
enum_state_t enum_state /*verilator fsm_reset_arc*/;
|
||
|
|
logic rst;
|
||
|
|
logic start;
|
||
|
|
integer cyc;
|
||
|
|
logic [39:0] forced_state /*verilator fsm_state*/;
|
||
|
|
logic [39:0] forced_case_if_state /*verilator fsm_state*/;
|
||
|
|
logic [47:0] param_state_q;
|
||
|
|
logic [47:0] param_state_d;
|
||
|
|
|
||
|
|
initial begin
|
||
|
|
rst = 1'b1;
|
||
|
|
start = 1'b0;
|
||
|
|
cyc = 0;
|
||
|
|
end
|
||
|
|
|
||
|
|
always @(posedge clk) begin
|
||
|
|
cyc <= cyc + 1;
|
||
|
|
if (cyc == 1) rst <= 1'b0;
|
||
|
|
if (cyc == 2) start <= 1'b1;
|
||
|
|
if (cyc == 3) start <= 1'b0;
|
||
|
|
if (cyc == 8) begin
|
||
|
|
$write("*-* All Finished *-*\n");
|
||
|
|
$finish;
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
always_ff @(posedge clk) begin
|
||
|
|
if (rst) begin
|
||
|
|
enum_state <= E_S0_IDLE;
|
||
|
|
end
|
||
|
|
else begin
|
||
|
|
case (enum_state)
|
||
|
|
E_S0_IDLE: enum_state <= start ? E_S1_BUSY : E_S0_IDLE;
|
||
|
|
E_S1_BUSY: enum_state <= E_S2_DONE;
|
||
|
|
default: enum_state <= E_S0_IDLE;
|
||
|
|
endcase
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
always_ff @(posedge clk) begin
|
||
|
|
if (rst) begin
|
||
|
|
forced_state <= 40'h0000_0000_01;
|
||
|
|
end
|
||
|
|
else begin
|
||
|
|
case (forced_state)
|
||
|
|
40'h0000_0000_01: forced_state <= start ? 40'h8000_0000_02 : 40'h0000_0000_01;
|
||
|
|
40'h8000_0000_02: forced_state <= 40'hffff_0000_03;
|
||
|
|
default: forced_state <= 40'h0000_0000_01;
|
||
|
|
endcase
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
always_ff @(posedge clk) begin
|
||
|
|
if (rst) begin
|
||
|
|
forced_case_if_state <= 40'h0000_0000_01;
|
||
|
|
end
|
||
|
|
else begin
|
||
|
|
case (forced_case_if_state)
|
||
|
|
40'h0000_0000_01: begin
|
||
|
|
if (start) begin
|
||
|
|
forced_case_if_state <= 40'h8000_0000_02;
|
||
|
|
end
|
||
|
|
else begin
|
||
|
|
forced_case_if_state <= 40'h0000_0000_01;
|
||
|
|
end
|
||
|
|
end
|
||
|
|
40'h8000_0000_02: forced_case_if_state <= 40'h0000_0000_01;
|
||
|
|
default: forced_case_if_state <= 40'h0000_0000_01;
|
||
|
|
endcase
|
||
|
|
end
|
||
|
|
end
|
||
|
|
always_comb begin
|
||
|
|
param_state_d = param_state_q;
|
||
|
|
if (param_state_q == L_S0_IDLE) begin
|
||
|
|
param_state_d = start ? L_S1_BUSY : L_S0_IDLE;
|
||
|
|
end
|
||
|
|
else if (param_state_q == L_S1_BUSY) begin
|
||
|
|
param_state_d = L_S2_DONE;
|
||
|
|
end
|
||
|
|
else if (param_state_q == L_S2_DONE) begin
|
||
|
|
param_state_d = L_S0_IDLE;
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
always_ff @(posedge clk) begin
|
||
|
|
if (rst) begin
|
||
|
|
param_state_q <= L_S0_IDLE;
|
||
|
|
end
|
||
|
|
else begin
|
||
|
|
param_state_q <= param_state_d;
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
endmodule
|