data/full_repos/permissive/473322203/verilog/rtl/SPM_example.v
data/verilator_xmls/ec9df46a-fb4c-4031-937a-6e4f29efeda5.xml
module SPM_example #(
    parameter BITS = 32
)(

    input wb_clk_i,
    input wb_rst_i,
    input wbs_stb_i,
    input wbs_cyc_i,
    input wbs_we_i,
    input [3:0] wbs_sel_i,
    input [31:0] wbs_dat_i,
    input [31:0] wbs_adr_i,
    output reg wbs_ack_o,
    output reg [31:0] wbs_dat_o

);
    wire clk;
    wire rst;
    
    wire [31:0] rdata; 
    wire [31:0] wdata;
    wire [BITS-1:0] count;

    wire valid;
    wire [3:0] wstrb;
    wire [31:0] la_write;


    localparam X_OFF = 805306368, Y_OFF = 805306372, P0_OFF = 805306376, P1_OFF = 805306380;

    localparam S0 = 0, S1 = 1, S2 = 2, S3 = 3;
    reg [3:0] STATE, nstate;
    reg [7:0] CNT, ncnt;

    reg [31:0] X, Y;
    reg [63:0] P0;

    wire p;   

    assign valid = wbs_cyc_i && wbs_stb_i; 
    assign wstrb = wbs_sel_i & {4{wbs_we_i}};

    assign wdata = wbs_dat_i;


    assign clk =  wb_clk_i;
    assign rst =  wb_rst_i;

    always @(posedge clk or posedge rst) begin
        
        if(rst) begin
          X <= 32'b0;

        end
        else if(valid && wbs_we_i && (wbs_adr_i==X_OFF)) begin
          X <= wbs_dat_i;


        end
    end
    
    always @(posedge clk or posedge rst) begin

        if(rst) begin

            Y <= 32'b0;
        end
        else if(STATE==S1) Y <= Y >>1;
        else if(valid && wbs_we_i && (wbs_adr_i==Y_OFF)) begin
          Y <= wbs_dat_i;


        end
        
    end

    always@(posedge clk) begin
        if(valid && wbs_we_i && (wbs_adr_i==Y_OFF)) begin
            wbs_dat_o <= Y;
        end
        else if(valid && wbs_we_i && (wbs_adr_i==X_OFF)) begin
            wbs_dat_o <= X;
        end
        else if(valid && !wbs_we_i && (wbs_adr_i==P0_OFF) && STATE==S0) begin
            wbs_dat_o <= P0[31:0];

        end if(valid && !wbs_we_i && (wbs_adr_i==P1_OFF) && STATE==S0) begin
          wbs_dat_o <= P0[63:32];
        end
    end

    always@(posedge clk) begin
        if(wbs_ack_o) begin
          wbs_ack_o <= 1'b0;
        end
        else if((valid && !wbs_we_i && (wbs_adr_i==P1_OFF) && STATE==S0) || (valid && !wbs_we_i && (wbs_adr_i==P0_OFF) && STATE==S0) || (valid && wbs_we_i && (wbs_adr_i==Y_OFF)) || (valid && wbs_we_i && (wbs_adr_i==X_OFF))) begin
            wbs_ack_o <= 1'b1;
        end
    end









    always @(posedge clk or posedge rst) begin
        if(rst) begin
           P0 <= 64'b0;
        end
        else if(STATE==S1) 
            P0 <= {p, P0[63:1]};

    end

    always @(posedge clk or posedge rst) begin
        if(rst) begin
          STATE <= S0;
        end
        else 
            STATE <=nstate;
    end

    always @(*) begin
        case(STATE) 
            S0: if(valid && wbs_we_i && (wbs_adr_i==Y_OFF)) nstate=S1; else nstate=S0;
            S1: if(CNT==64) nstate=S0; else nstate=S1;
            default: nstate=S0; 
        endcase
    end

    always @(posedge clk or posedge rst) begin
        if(rst) begin
          CNT <= 8'b0;
        end
        else 
            CNT <= ncnt;
    end






    always @(*) begin
        ncnt = 0;
        if(CNT==64) ncnt <=0;
        else if(STATE==S1) ncnt = CNT + 1;
    end
    SPM spm(.clk(clk), .rst(rst), .x(X), .y(Y[0]), .p(p));
    

endmodule
module SPM_example #(
    parameter BITS = 32
)(

    input wb_clk_i,
    input wb_rst_i,
    input wbs_stb_i,
    input wbs_cyc_i,
    input wbs_we_i,
    input [3:0] wbs_sel_i,
    input [31:0] wbs_dat_i,
    input [31:0] wbs_adr_i,
    output reg wbs_ack_o,
    output reg [31:0] wbs_dat_o

);

    wire clk;
    wire rst;
    
    wire [31:0] rdata; 
    wire [31:0] wdata;
    wire [BITS-1:0] count;

    wire valid;
    wire [3:0] wstrb;
    wire [31:0] la_write;


    localparam X_OFF = 805306368, Y_OFF = 805306372, P0_OFF = 805306376, P1_OFF = 805306380;

    localparam S0 = 0, S1 = 1, S2 = 2, S3 = 3;
    reg [3:0] STATE, nstate;
    reg [7:0] CNT, ncnt;

    reg [31:0] X, Y;
    reg [63:0] P0;

    wire p;   

    assign valid = wbs_cyc_i && wbs_stb_i; 
    assign wstrb = wbs_sel_i & {4{wbs_we_i}};

    assign wdata = wbs_dat_i;


    assign clk =  wb_clk_i;
    assign rst =  wb_rst_i;

    always @(posedge clk or posedge rst) begin
        
        if(rst) begin
          X <= 32'b0;

        end
        else if(valid && wbs_we_i && (wbs_adr_i==X_OFF)) begin
          X <= wbs_dat_i;


        end
    end
    
    always @(posedge clk or posedge rst) begin

        if(rst) begin

            Y <= 32'b0;
        end
        else if(STATE==S1) Y <= Y >>1;
        else if(valid && wbs_we_i && (wbs_adr_i==Y_OFF)) begin
          Y <= wbs_dat_i;


        end
        
    end

    always@(posedge clk) begin
        if(valid && wbs_we_i && (wbs_adr_i==Y_OFF)) begin
            wbs_dat_o <= Y;
        end
        else if(valid && wbs_we_i && (wbs_adr_i==X_OFF)) begin
            wbs_dat_o <= X;
        end
        else if(valid && !wbs_we_i && (wbs_adr_i==P0_OFF) && STATE==S0) begin
            wbs_dat_o <= P0[31:0];

        end if(valid && !wbs_we_i && (wbs_adr_i==P1_OFF) && STATE==S0) begin
          wbs_dat_o <= P0[63:32];
        end
    end

    always@(posedge clk) begin
        if(wbs_ack_o) begin
          wbs_ack_o <= 1'b0;
        end
        else if((valid && !wbs_we_i && (wbs_adr_i==P1_OFF) && STATE==S0) || (valid && !wbs_we_i && (wbs_adr_i==P0_OFF) && STATE==S0) || (valid && wbs_we_i && (wbs_adr_i==Y_OFF)) || (valid && wbs_we_i && (wbs_adr_i==X_OFF))) begin
            wbs_ack_o <= 1'b1;
        end
    end









    always @(posedge clk or posedge rst) begin
        if(rst) begin
           P0 <= 64'b0;
        end
        else if(STATE==S1) 
            P0 <= {p, P0[63:1]};

    end

    always @(posedge clk or posedge rst) begin
        if(rst) begin
          STATE <= S0;
        end
        else 
            STATE <=nstate;
    end

    always @(*) begin
        case(STATE) 
            S0: if(valid && wbs_we_i && (wbs_adr_i==Y_OFF)) nstate=S1; else nstate=S0;
            S1: if(CNT==64) nstate=S0; else nstate=S1;
            default: nstate=S0; 
        endcase
    end

    always @(posedge clk or posedge rst) begin
        if(rst) begin
          CNT <= 8'b0;
        end
        else 
            CNT <= ncnt;
    end






    always @(*) begin
        ncnt = 0;
        if(CNT==64) ncnt <=0;
        else if(STATE==S1) ncnt = CNT + 1;
    end
    SPM spm(.clk(clk), .rst(rst), .x(X), .y(Y[0]), .p(p));
    

endmodule