dakies/OSS_Verilog huggingface dataset:
module core_top
(
  input wire 	      clk, 
  input wire 	      resetb,
  //output wire [13:2] rom_addr, 
  //input wire [31:0]  rom_data, 
  //output wire [13:2] rom_addr_2, 
  //input wire [31:0]  rom_data_2, 
  output wire [7:0]  io_addr,
  output wire 	      io_en, 
  output wire 	      io_we, 
  input wire [31:0]  io_data_read, 
  output wire [31:0] io_data_write,
  input wire irq_mtimecmp
  //input wire mtime_we,
  //output wire [31:0] mtime_dout
);

wire 	      dm_we;
wire [31:0] 	      im_addr;
wire [31:0] 	      im_do;
wire [31:0] 	      dm_addr;
wire [31:0] 	      dm_di;
wire [31:0] 	      dm_do;
wire [3:0] 	      dm_be;
wire 	      dm_is_signed;

core CPU0
(
  .clk(clk), .resetb(resetb),
  .dm_we(dm_we), .im_addr(im_addr), .im_do(im_do),
  .dm_addr(dm_addr), .dm_di(dm_di), .dm_do(dm_do),
  .dm_be(dm_be), .dm_is_signed(dm_is_signed),
  .irq_mtimecmp(irq_mtimecmp)
);

mmu MMU0
(
  .clk(clk), .resetb(resetb),
  .dm_we(dm_we),
  .im_addr(im_addr), .im_do(im_do),
  .dm_addr(dm_addr), .dm_di(dm_di), .dm_do(dm_do),
  .dm_be(dm_be), .is_signed(dm_is_signed),
  //.im_addr_out(rom_addr), .im_data(rom_data),
  //.im_addr_out_2(rom_addr_2), .im_data_2(rom_data_2),
  .io_addr(io_addr), .io_en(io_en), .io_we(io_we),
  .io_data_read(io_data_read), .io_data_write(io_data_write)
);


endmodule
module timer(
  input wire clk,
  input wire resetb,
  // No io_en signal since read has no side effect
  input wire [3:2] io_addr_3_2,
    input wire io_we,
    input wire [31:0] io_din,
    output wire [31:0] io_dout,
    // mtimecmp port
    // IRQ
    output reg irq_mtimecmp
    );

    reg [63:0] mtime;
    reg [63:0] mtimecmp;

    always @ (posedge clk) begin : TIMER_PIPELINE
      if (!resetb) begin
        mtime <= 64'b0;
        // mtimecmp <= 64'hFFFFFFFFFFFFFFFF;
        mtimecmp <= 64'b0;
        irq_mtimecmp <= 1'b0;
      end
      else if (clk) begin
        mtime <= mtime + 1;
        if (io_we) begin
          case (io_addr_3_2[3:2])
            2'b00: mtime[0+:32] <= io_din;
            2'b01: mtime[32+:32] <= io_din;
            2'b10: begin 
            mtimecmp[0+:32] <= io_din;
            irq_mtimecmp <= 1'b0;
          end
          2'b11: begin 
          mtimecmp[32+:32] <= io_din;
          irq_mtimecmp <= 1'b0;
        end
      endcase
    end
    if (mtime == mtimecmp) begin
      irq_mtimecmp <= 1'b1;
    end
  end
end

assign io_dout = 
  io_addr_3_2[3]
  ? ( io_addr_3_2[2] ? mtimecmp[32+:32] : mtimecmp[0+:32] )
  : ( io_addr_3_2[2] ? mtime[32+:32] : mtime[0+:32] );

  endmodule
module io_port
  (
   input wire 	      clk,
   input wire 	      resetb,
   /* verilator lint_off UNUSED */
   input wire [7:0]   io_addr/*verilator public*/,
   input wire 	      io_en/*verilator public*/,
   /* verilator lint_on UNUSED */
   input wire 	      io_we/*verilator public*/,
   input wire [31:0]  io_data_write/*verilator public*/,
   output wire [31:0] io_data_read,
   output wire 	      irq_mtimecmp,
   output reg [7:0]   gpio0
   );

   wire 	      mtime_we;
   wire [31:0] 	      mtime_dout;

   assign mtime_we = io_addr[7:4] == 4'b0001 ? io_we : 1'b0;

   assign io_data_read = io_addr[7:4] == 4'b0001 ? mtime_dout : 32'bX;

   // GPIO0 is at 0x80000000, the same address as testbench commands.
   // However, it only uses the lowest byte
   always @ (posedge clk) begin : GPIO0
      if (!resetb) begin
	 gpio0 <= 8'b0;
      end
      else if (clk) begin
	 if (io_addr[7:2] == 6'b0 && io_we) begin
	    gpio0 <= io_data_write[7:0];
	 end
      end
   end

   timer TIMER0
     (
      .clk(clk), .resetb(resetb),
      .io_addr_3_2(io_addr[3:2]), .io_we(mtime_we), .io_din(io_data_write),
      .io_dout(mtime_dout), .irq_mtimecmp(irq_mtimecmp)
      );

endmodule
module SPRAM_16Kx16
  (
   input wire [13:0] addr,
   input wire [15:0] din,
   input wire [3:0] maskwren,
   input wire wren,
   input wire clk,
   output reg [15:0] dout
   );
   
   reg [15:0] 	     RAM [16383:0] /*verilator public*/;

   always @ (posedge clk) begin
      if (wren) begin
	 if (maskwren[0]) RAM[addr][0+:4]   <= din[0+:4];
	 if (maskwren[1]) RAM[addr][4+:4]   <= din[4+:4];
	 if (maskwren[2]) RAM[addr][8+:4]   <= din[8+:4];
	 if (maskwren[3]) RAM[addr][12+:4]   <= din[12+:4];
      end
      else begin
	dout <= RAM[addr];
      end
   end
endmodule // SB_SPRAM256KA
module board_top
  (
   input wire clki,
   input wire resetb,
   output wire [7:0] gpio0
   );

   wire 	     clk;
   SB_GB clk_gb(.USER_SIGNAL_TO_GLOBAL_BUFFER(clki),
		.GLOBAL_BUFFER_OUTPUT(clk));

   cpu_top U0(.clk(clk), .resetb(resetb), .gpio0(gpio0));
   
endmodule // board_top
module SB_SPRAM256KA (
        input [13:0] ADDRESS,
        input [15:0] DATAIN,
        input [3:0] MASKWREN,
        input WREN, CHIPSELECT, CLOCK, STANDBY, SLEEP, POWEROFF,
        output reg [15:0] DATAOUT
);
        reg [15:0] mem [0:16383];
        wire off = SLEEP || !POWEROFF;
        integer i;

        always @(negedge POWEROFF) begin
                for (i = 0; i <= 16383; i = i+1)
                        mem[i] = 'bx;
        end

        always @(posedge CLOCK, posedge off) begin
                if (off) begin
                        DATAOUT <= 0;
                end else
                if (CHIPSELECT && !STANDBY && !WREN) begin
                        DATAOUT <= mem[ADDRESS];
                end else begin
                        if (CHIPSELECT && !STANDBY && WREN) begin
                                if (MASKWREN[0]) mem[ADDRESS][ 3: 0] = DATAIN[ 3: 0];
                                if (MASKWREN[1]) mem[ADDRESS][ 7: 4] = DATAIN[ 7: 4];
                                if (MASKWREN[2]) mem[ADDRESS][11: 8] = DATAIN[11: 8];
                                if (MASKWREN[3]) mem[ADDRESS][15:12] = DATAIN[15:12];
                        end
                        DATAOUT <= 'bx;
                end
        end
endmodule
module BRAM_SSP(
		clk, we, en, addr, din, dout
		);
   parameter 
     DEPTH = 256,
     DEPTH_LOG = 8,
     WIDTH = 32;
   
   input clk, we, en;
   input [DEPTH_LOG-1:0] addr;
   input [WIDTH-1:0] 	 din;
   output [WIDTH-1:0] 	 dout;

   reg [WIDTH-1:0] 	 RAM [DEPTH-1:0] /*verilator public*/;
   reg [WIDTH-1:0] 	 dout;

   always @ (posedge clk) begin
      if (en & we) begin
	    RAM[addr]   <= din;
	    dout <= din;
      end
      else
	dout <= RAM[addr];
   end
   
endmodule // BRAM_SSP
module EBRAM_ROM(
		clk, 
                addra, douta, addrb, doutb
		);
   parameter 
     DEPTH = 512,
     DEPTH_LOG = 9,
     WIDTH = 32;
   
   input wire clk;
   input wire [DEPTH_LOG-1:0] addra, addrb;
   output reg [WIDTH-1:0] 	 douta, doutb;

   reg [WIDTH-1:0] 	 ROM [DEPTH-1:0] /*verilator public*/;

   always @ (posedge clk) begin
	douta <= ROM[addra];
	doutb <= ROM[addrb];
   end
   
endmodule // BRAM_SSP
module SPRAM_16Kx16
  (
   input wire [13:0] addr,
   input wire [15:0] din,
   input wire [3:0] maskwren,
   input wire wren,
   input wire clk,
   output wire [15:0] dout
   );

   SB_SPRAM256KA ram0
     (
      .ADDRESS(addr),
      .DATAIN(din),
      .MASKWREN(maskwren),
      .CHIPSELECT(1'b1),
      .CLOCK(clk),
      .STANDBY(1'b0),
      .SLEEP(1'b0),
      .POWEROFF(1'b0),
      .DATAOUT(dout)
      );

endmodule
module regfile(
	       input wire 	  clk, input wire resetb,
	       input wire [4:0]   a_rs1,
	       output reg [31:0] d_rs1,
	       input wire [4:0]   a_rs2,
	       output reg [31:0] d_rs2,
	       input wire [4:0]   a_rd,
	       input wire [31:0] d_rd,
	       input wire we_rd
	       );

   // 32x32 registers
   reg [31:0] 		  data [0:31] /*verilator public*/;
   // Temporary variable
   integer 		  i;

   always @ (posedge clk) begin : MAIN_CLK_PROCESS
      if (!resetb) begin
	 // Registers do not initialize
	 for (i = 0; i < 32; i = i + 1) begin
	    data[i] <= 32'bX;
	 end
      end
      else if (clk) begin
	 // Write back
	 if (we_rd) begin
	    data[a_rd] <= d_rd;
	 end
      end
   end // block: MAIN_CLK_PROCESS

   always @ (*) begin : COMBINATIONAL_PROCESS
      // Forwarding rs1
      if (a_rs1 == 5'b0)
	d_rs1 = 32'b0;
      else if (we_rd && a_rd != 5'b0 && a_rs1 == a_rd)
	d_rs1 = d_rd;
      else
	d_rs1 = data[a_rs1];
      // Forwarding rs2
      if (a_rs2 == 5'b0)
	d_rs2 = 32'b0;
      else if (we_rd && a_rd != 5'b0 && a_rs2 == a_rd)
	d_rs2 = d_rd;
      else
	d_rs2 = data[a_rs2];
   end
   
endmodule // regfile
module cpu_top
  (
   input wire clk,
   input wire resetb,
   output wire [7:0] gpio0
   );

   wire [7:0] io_addr;
   wire       io_en, io_we;
   wire [31:0] io_data_read;
   wire [31:0] io_data_write;
   wire        irq_mtimecmp;

   core_top CT0 
     (
      .clk(clk), .resetb(resetb),
      .io_addr(io_addr), .io_en(io_en), .io_we(io_we),
      .io_data_read(io_data_read), .io_data_write(io_data_write),
      .irq_mtimecmp(irq_mtimecmp)
      );

   io_port IO0
     (
      .clk(clk), .resetb(resetb),
      .io_addr(io_addr), .io_en(io_en), .io_we(io_we),
      .io_data_read(io_data_read), .io_data_write(io_data_write),
      .irq_mtimecmp(irq_mtimecmp),
      .gpio0(gpio0)
      );


endmodule
module core_top
  (
   input wire 	      clk, 
   input wire 	      resetb,
   output wire [11:2] rom_addr, 
   input wire [31:0]  rom_data, 
   output wire [7:0]  io_addr,
   output wire 	      io_en, 
   output wire 	      io_we, 
   input wire [31:0]  io_data_read, 
   output wire [31:0] io_data_write
   );

   wire 	      dm_we;
   wire [31:0] 	      im_addr;
   wire [31:0] 	      im_do;
   wire [31:0] 	      dm_addr;
   wire [31:0] 	      dm_di;
   wire [31:0] 	      dm_do;
   wire [3:0] 	      dm_be;
   wire 	      dm_is_signed;
   
   core CPU0
     (
      .clk(clk), .resetb(resetb),
      .dm_we(dm_we), .im_addr(im_addr), .im_do(im_do),
      .dm_addr(dm_addr), .dm_di(dm_di), .dm_do(dm_do),
      .dm_be(dm_be), .dm_is_signed(dm_is_signed)
      );

   mmu MMU0
     (
      .clk(clk), .resetb(resetb),
      .dm_we(dm_we), .im_addr(im_addr), .im_do(im_do),
      .dm_addr(dm_addr), .dm_di(dm_di), .dm_do(dm_do),
      .dm_be(dm_be), .is_signed(dm_is_signed),
      .im_addr_out(rom_addr), .im_data(rom_data),
      .io_addr(io_addr), .io_en(io_en), .io_we(io_we),
      .io_data_read(io_data_read), .io_data_write(io_data_write)
      );

endmodule
module regfile(
	       input wire 	  clk, input wire resetb,
	       input wire [4:0]   a_rs1,
	       output reg [31:0] d_rs1,
	       input wire [4:0]   a_rs2,
	       output reg [31:0] d_rs2,
	       input wire [4:0]   a_rd,
	       input wire [31:0] d_rd,
	       input wire we_rd
	       );

   // 32x32 registers
   reg [31:0] 		  data [0:31];
   // Temporary variable
   integer 		  i;

   always @ (posedge clk, negedge resetb) begin : MAIN_CLK_PROCESS
      if (!resetb) begin
	 // Registers do not initialize
	 for (i = 0; i < 32; i = i + 1) begin
	    data[i] <= 32'bX;
	 end
      end
      else if (clk) begin
	 // Write back
	 if (we_rd) begin
	    data[a_rd] <= d_rd;
	 end
      end
   end // block: MAIN_CLK_PROCESS

   always @ (*) begin : COMBINATIONAL_PROCESS
      // Forwarding rs1
      if (a_rs1 == 5'b0)
	d_rs1 = 32'b0;
      else if (we_rd && a_rd != 5'b0 && a_rs1 == a_rd)
	d_rs1 = d_rd;
      else
	d_rs1 = data[a_rs1];
      // Forwarding rs2
      if (a_rs2 == 5'b0)
	d_rs2 = 32'b0;
      else if (we_rd && a_rd != 5'b0 && a_rs2 == a_rd)
	d_rs2 = d_rd;
      else
	d_rs2 = data[a_rs2];
   end
   
endmodule // regfile
module iob_cache_onehot_to_bin #(
   parameter BIN_W = 2
) (
   input      [2**BIN_W-1:1] onehot_i,
   output reg [   BIN_W-1:0] bin_o
);

   reg     [BIN_W-1:0] bin_cnt;
   integer             i;

   always @(onehot_i) begin : onehot_to_binary_encoder
      bin_cnt = 0;
      for (i = 1; i < 2 ** BIN_W; i = i + 1) if (onehot_i[i]) bin_cnt = bin_cnt | i[BIN_W-1:0];
      bin_o = bin_cnt;
   end

endmodule
module iob_cache_tb;

   //clock
   parameter clk_per = 10;
   reg clk = 1;
   always #clk_per clk = ~clk;

   parameter FE_ADDR_W    = `IOB_CACHE_FE_ADDR_W;
   parameter FE_DATA_W    = `IOB_CACHE_FE_DATA_W;
   parameter FE_NBYTES    = FE_DATA_W / 8;
   parameter FE_NBYTES_W  = $clog2(FE_NBYTES);
   parameter USE_CTRL     = `IOB_CACHE_USE_CTRL;
   parameter USE_CTRL_CNT = `IOB_CACHE_USE_CTRL_CNT;

   parameter ADDR_W       = USE_CTRL+FE_ADDR_W-FE_NBYTES_W;
   parameter DATA_W       = `IOB_CACHE_DATA_W;

   reg                                       rst = 1;

   //frontend signals
`include "iob_m_tb_wire.vs"
   reg                                       ctrl = 0;

   //iterator
   integer i, fd, failed=0;

   reg [DATA_W-1:0] rdata;
   

   //test process
   initial begin
`ifdef VCD
      $dumpfile("uut.vcd");
      $dumpvars();
`endif
      repeat (5) @(posedge clk);
      rst = 0;
      #10;

      $display("Writing data to frontend");
      for (i = 0; i < 5*4; i = i + 4) begin
         iob_write(i, (3*i), `IOB_CACHE_DATA_W);
      end

      #80 @(posedge clk);

      $display("Reading data from frontend");
      for (i = 0; i < 5*4; i = i + 4) begin
         iob_read(i, rdata, `IOB_CACHE_DATA_W);
         //Write "Test passed!" to a file named "test.log"
         if (rdata !== (3*i)) begin
            $display("ERROR at address %d: got 0x%0h, expected 0x%0h", i, rdata, 3*i);
             failed = failed+1;
         end
      end

      #100;

      fd = $fopen("test.log", "w");

      if (failed == 0) begin
         $display("Test passed!");
         $fwrite(fd, "Test passed!");
      end else begin
         $display("Test failed!");
         $fwrite(fd, "Test failed!");
      end
      $fclose(fd);
      $finish();
   end

   //Unit Under Test (simulation wrapper)
   iob_cache_sim_wrapper uut (
      //frontend
`include "iob_s_s_portmap.vs"
      //invalidate / wtb empty
      .invalidate_i (1'b0),
      .invalidate_o(),
      .wtb_empty_i  (1'b1),
      .wtb_empty_o (),

      .clk_i(clk),
      .arst_i(rst)
   );

`include "iob_tasks.vs"

endmodule
module top(
`ifdef VGA
  // VGA
  output out_video_clock,
  output reg [`COLOR_DEPTH-1:0] out_video_r,
  output reg [`COLOR_DEPTH-1:0] out_video_g,
  output reg [`COLOR_DEPTH-1:0] out_video_b,
  output out_video_hs,
  output out_video_vs,
`endif
  // basic
  output [7:0] out_leds,
  input        clock
);

reg [2:0] ready = 3'b111;

always @(posedge clock) begin
  ready <= ready >> 1;
end

wire run_main;
assign run_main = 1'b1;

M_main __main(
  .clock(clock),
  .reset(ready[0]),
  .out_leds(out_leds),
`ifdef VGA
  .out_video_clock(out_video_clock),
  .out_video_r(out_video_r),
  .out_video_g(out_video_g),
  .out_video_b(out_video_b),
  .out_video_hs(out_video_hs),
  .out_video_vs(out_video_vs),
`endif
  .in_run(run_main)
);

endmodule
module M_main__mem_mem(
input      [11-1:0]                in_mem_addr,
output reg  [32-1:0]    out_mem_rdata,
input      [(32)/8-1:0]         in_mem_wenable,
input      [32-1:0]                in_mem_wdata,
input      clock
);
reg  [32-1:0] buffer[1536-1:0];
always @(posedge clock) begin
  out_mem_rdata <= buffer[in_mem_addr];
end
integer i;
always @(posedge clock) begin
  for (i = 0; i < (32)/8; i = i + 1) begin
    if (in_mem_wenable[i]) begin
      buffer[in_mem_addr][i*8+:8] <= in_mem_wdata[i*8+:8];
    end
  end
end
initial begin
 buffer[0] = 32'h00002137;
 buffer[1] = 32'h80010113;
 buffer[2] = 32'h00000097;
 buffer[3] = 32'h018080E7;
 buffer[4] = 32'h00000317;
 buffer[5] = 32'h00830067;
 buffer[6] = 32'h00000000;
 buffer[7] = 32'h00008067;
 buffer[8] = 32'hFF010113;
 buffer[9] = 32'h00012623;
 buffer[10] = 32'h000027B7;
 buffer[11] = 32'h00F00713;
 buffer[12] = 32'h00E7A223;
 buffer[13] = 32'h00200793;
 buffer[14] = 32'h000026B7;
 buffer[15] = 32'h00800713;
 buffer[16] = 32'h0080006F;
 buffer[17] = 32'h00100793;
 buffer[18] = 32'h00F6A223;
 buffer[19] = 32'h00179793;
 buffer[20] = 32'hFEF74AE3;
 buffer[21] = 32'hFF5FF06F;
 buffer[22] = 32'h00002040;
 buffer[23] = 32'h00002020;
 buffer[24] = 32'h00002010;
 buffer[25] = 32'h00002008;
 buffer[26] = 32'h00002004;
end

endmodule
module M_rv32i_cpu__cpu_mem_xregsA(
input                  [1-1:0] in_xregsA_wenable,
input      signed [32-1:0]    in_xregsA_wdata,
input                  [5-1:0]    in_xregsA_addr,
output reg signed [32-1:0]    out_xregsA_rdata,
input                                      clock
);
reg signed [32-1:0] buffer[32-1:0];
always @(posedge clock) begin
  if (in_xregsA_wenable) begin
    buffer[in_xregsA_addr] <= in_xregsA_wdata;
  end
  out_xregsA_rdata <= buffer[in_xregsA_addr];
end
initial begin
 buffer[0] = 0;
 buffer[1] = 0;
 buffer[2] = 0;
 buffer[3] = 0;
 buffer[4] = 0;
 buffer[5] = 0;
 buffer[6] = 0;
 buffer[7] = 0;
 buffer[8] = 0;
 buffer[9] = 0;
 buffer[10] = 0;
 buffer[11] = 0;
 buffer[12] = 0;
 buffer[13] = 0;
 buffer[14] = 0;
 buffer[15] = 0;
 buffer[16] = 0;
 buffer[17] = 0;
 buffer[18] = 0;
 buffer[19] = 0;
 buffer[20] = 0;
 buffer[21] = 0;
 buffer[22] = 0;
 buffer[23] = 0;
 buffer[24] = 0;
 buffer[25] = 0;
 buffer[26] = 0;
 buffer[27] = 0;
 buffer[28] = 0;
 buffer[29] = 0;
 buffer[30] = 0;
 buffer[31] = 0;
end

endmodule
module M_rv32i_cpu__cpu_mem_xregsB(
input                  [1-1:0] in_xregsB_wenable,
input      signed [32-1:0]    in_xregsB_wdata,
input                  [5-1:0]    in_xregsB_addr,
output reg signed [32-1:0]    out_xregsB_rdata,
input                                      clock
);
reg signed [32-1:0] buffer[32-1:0];
always @(posedge clock) begin
  if (in_xregsB_wenable) begin
    buffer[in_xregsB_addr] <= in_xregsB_wdata;
  end
  out_xregsB_rdata <= buffer[in_xregsB_addr];
end
initial begin
 buffer[0] = 0;
 buffer[1] = 0;
 buffer[2] = 0;
 buffer[3] = 0;
 buffer[4] = 0;
 buffer[5] = 0;
 buffer[6] = 0;
 buffer[7] = 0;
 buffer[8] = 0;
 buffer[9] = 0;
 buffer[10] = 0;
 buffer[11] = 0;
 buffer[12] = 0;
 buffer[13] = 0;
 buffer[14] = 0;
 buffer[15] = 0;
 buffer[16] = 0;
 buffer[17] = 0;
 buffer[18] = 0;
 buffer[19] = 0;
 buffer[20] = 0;
 buffer[21] = 0;
 buffer[22] = 0;
 buffer[23] = 0;
 buffer[24] = 0;
 buffer[25] = 0;
 buffer[26] = 0;
 buffer[27] = 0;
 buffer[28] = 0;
 buffer[29] = 0;
 buffer[30] = 0;
 buffer[31] = 0;
end

endmodule
module M_main (
out_leds,
in_run,
out_done,
reset,
out_clock,
clock
);
output  [4:0] out_leds;
input in_run;
output out_done;
input reset;
output out_clock;
input clock;
assign out_clock = clock;
wire  [11:0] _w_cpu_mem_addr;
wire  [3:0] _w_cpu_mem_wenable;
wire  [31:0] _w_cpu_mem_wdata;
wire _w_cpu_done;
wire  [31:0] _w_mem_mem_rdata;
wire  [0:0] _c_reg_miso;
assign _c_reg_miso = 0;
reg  [0:0] _t_prev_mem_rw;
reg  [31:0] _t_memio_rdata;
reg  [31:0] _t_mem_wenable;
reg  [31:0] _t_mem_wdata;
reg  [10:0] _t_mem_addr;

reg  [11:0] _d_prev_mem_addr = 0;
reg  [11:0] _q_prev_mem_addr = 0;
reg  [31:0] _d_cycle = 0;
reg  [31:0] _q_cycle = 0;
reg  [4:0] _d_leds;
reg  [4:0] _q_leds;
reg  [1:0] _d_index,_q_index = 3;
reg  _autorun = 0;
reg  _cpu_run = 0;
assign out_leds = _q_leds;
assign out_done = (_q_index == 3) & _autorun;
M_rv32i_cpu__cpu cpu (
.in_mem_rdata(_t_memio_rdata),
.out_mem_addr(_w_cpu_mem_addr),
.out_mem_wenable(_w_cpu_mem_wenable),
.out_mem_wdata(_w_cpu_mem_wdata),
.out_done(_w_cpu_done),
.in_run(_cpu_run),
.reset(reset),
.clock(clock));

M_main__mem_mem __mem__mem(
.clock(clock),
.in_mem_wenable(_t_mem_wenable),
.in_mem_wdata(_t_mem_wdata),
.in_mem_addr(_t_mem_addr),
.out_mem_rdata(_w_mem_mem_rdata)
);


`ifdef FORMAL
initial begin
assume(reset);
end
assume property($initstate || (out_done));
`endif
always @* begin
_d_prev_mem_addr = _q_prev_mem_addr;
_d_cycle = _q_cycle;
_d_leds = _q_leds;
_d_index = _q_index;
_cpu_run = 1;
// _always_pre
// __block_1
_t_mem_wenable = _w_cpu_mem_wenable&{4{~_w_cpu_mem_addr[11+:1]}};
_t_memio_rdata = (_q_prev_mem_addr[11+:1]&_q_prev_mem_addr[4+:1]) ? {31'b0,_c_reg_miso}:_w_mem_mem_rdata;
_d_prev_mem_addr = _w_cpu_mem_addr;
_t_prev_mem_rw = _w_cpu_mem_wenable[0+:1];
_t_mem_wdata = _w_cpu_mem_wdata;
_t_mem_addr = _w_cpu_mem_addr;
if (_w_cpu_mem_addr[11+:1]) begin
// __block_2
// __block_4
_d_leds = _t_mem_wdata[0+:5]&{5{_w_cpu_mem_addr[0+:1]}};
if (_w_cpu_mem_addr[0+:1]) begin
// __block_5
// __block_7
$display("[cycle %d] LEDs: %b",_q_cycle,_d_leds);
// __block_8
end else begin
// __block_6
end
// __block_9
if (_w_cpu_mem_addr[4+:1]) begin
// __block_10
// __block_12
$display("[cycle %d] SPI write %b",_q_cycle,_t_mem_wdata[0+:3]);
// __block_13
end else begin
// __block_11
end
// __block_14
// __block_15
end else begin
// __block_3
end
// __block_16
_d_cycle = _q_cycle+1;
// __block_17
(* full_case *)
case (_q_index)
0: begin
// _top
_cpu_run = 0;
_d_index = 1;
end
1: begin
// __block_18
if (_w_cpu_done == 1) begin
_d_index = 2;
end else begin
_d_index = 1;
end
end
2: begin
// __block_19
_d_index = 3;
end
3: begin // end of 
end
default: begin 
_d_index = {2{1'bx}};
`ifdef FORMAL
assume(0);
`endif
 end
endcase
// _always_post
end

always @(posedge clock) begin
_q_prev_mem_addr <= _d_prev_mem_addr;
_q_cycle <= _d_cycle;
_q_leds <= _d_leds;
_q_index <= reset ? 3 : ( ~_autorun ? 0 : _d_index);
_autorun <= reset ? 0 : 1;
end

endmodule
module M_main (
out_leds,
in_run,
out_done,
reset,
out_clock,
clock
);
output  [7:0] out_leds;
input in_run;
output out_done;
input reset;
output out_clock;
input clock;
assign out_clock = clock;
wire signed [15:0] _w_mul_ret;
wire _w_mul_done;
reg signed [15:0] _t_result;

reg signed [15:0] _d_m0;
reg signed [15:0] _q_m0;
reg signed [15:0] _d_m1;
reg signed [15:0] _q_m1;
reg  [7:0] _d_leds;
reg  [7:0] _q_leds;
reg signed [15:0] _d_mul_im0,_q_mul_im0;
reg signed [15:0] _d_mul_im1,_q_mul_im1;
reg  [3:0] _d_index,_q_index = 13;
reg  _autorun = 0;
assign out_leds = _q_leds;
assign out_done = (_q_index == 13) & _autorun;
M_mulpip16__mul mul (
.in_im0(_d_mul_im0),
.in_im1(_d_mul_im1),
.out_ret(_w_mul_ret),
.out_done(_w_mul_done),
.reset(reset),
.clock(clock));



`ifdef FORMAL
initial begin
assume(reset);
end
assume property($initstate || (out_done));
`endif
always @* begin
_d_m0 = _q_m0;
_d_m1 = _q_m1;
_d_leds = _q_leds;
_d_mul_im0 = _q_mul_im0;
_d_mul_im1 = _q_mul_im1;
_d_index = _q_index;
// _always_pre
_t_result = _w_mul_ret;
_d_mul_im0 = _q_m0;
_d_mul_im1 = _q_m1;
_d_leds = _t_result[0+:8];
(* full_case *)
case (_q_index)
0: begin
// _top
_d_m0 = 2;
_d_m1 = 3;
$display("%d * %d = ...",_d_m0,_d_m1);
_d_index = 1;
end
1: begin
// __block_1
_d_m0 = _q_m0+1;
_d_m1 = -_q_m1-1;
$display("%d * %d = ...",_d_m0,_d_m1);
_d_index = 2;
end
2: begin
// __block_2
_d_m0 = _q_m0+1;
_d_m1 = -_q_m1+1;
$display("%d * %d = ...",_d_m0,_d_m1);
_d_index = 3;
end
3: begin
// __block_3
_d_m0 = _q_m0+1;
_d_m1 = -_q_m1-1;
$display("%d * %d = ...",_d_m0,_d_m1);
_d_index = 4;
end
4: begin
// __block_4
_d_m0 = _q_m0+1;
_d_m1 = -_q_m1+1;
$display("%d * %d = ...",_d_m0,_d_m1);
_d_index = 5;
end
5: begin
// __block_5
_d_m0 = _q_m0+1;
_d_m1 = -_q_m1-1;
$display("%d * %d = ...",_d_m0,_d_m1);
_d_index = 6;
end
6: begin
// __block_6
$display("... = %d",_t_result);
_d_index = 7;
end
7: begin
// __block_7
$display("... = %d",_t_result);
_d_index = 8;
end
8: begin
// __block_8
$display("... = %d",_t_result);
_d_index = 9;
end
9: begin
// __block_9
$display("... = %d",_t_result);
_d_index = 10;
end
10: begin
// __block_10
$display("... = %d",_t_result);
_d_index = 11;
end
11: begin
// __block_11
$display("... = %d",_t_result);
_d_index = 12;
end
12: begin
// __block_12
_d_index = 13;
end
13: begin // end of 
end
default: begin 
_d_index = {4{1'bx}};
`ifdef FORMAL
assume(0);
`endif
 end
endcase
// _always_post
end

always @(posedge clock) begin
_q_m0 <= (reset) ? 0 : _d_m0;
_q_m1 <= (reset) ? 0 : _d_m1;
_q_leds <= (reset) ? 0 : _d_leds;
_q_index <= reset ? 13 : ( ~_autorun ? 0 : _d_index);
_autorun <= reset ? 0 : 1;
_q_mul_im0 <= _d_mul_im0;
_q_mul_im1 <= _d_mul_im1;
end

endmodule
module multest(clock, out);

input clock;
output reg [7:0] out = 0;
reg [7:0] a = 0;
// reg [7:0] b = 0;

always @(posedge clock)
begin
	out <= a * a;
  a   <= a + 1;
//  b   <= b + 1;
end

endmodule
module counter(clock, out);

input clock;
output reg [8:0] out = 0;

always @(posedge clock)
begin
	out <= out + 1;
end

endmodule
module M_div16__div0 (
in_inum,
in_iden,
out_ret,
in_run,
out_done,
reset,
out_clock,
clock
);
input signed [15:0] in_inum;
input signed [15:0] in_iden;
output signed [15:0] out_ret;
input in_run;
output out_done;
input reset;
output out_clock;
input clock;
assign out_clock = clock;
wire  [16:0] _w_diff;
wire  [15:0] _w_num;
wire  [15:0] _w_den;

reg  [16:0] _d_ac;
reg  [16:0] _q_ac;
reg  [4:0] _d_i;
reg  [4:0] _q_i;
reg signed [15:0] _d_ret;
reg signed [15:0] _q_ret;
reg  [1:0] _d_index,_q_index = 3;
assign out_ret = _q_ret;
assign out_done = (_q_index == 3);


assign _w_diff = _q_ac-_w_den;
assign _w_num = in_inum;
assign _w_den = in_iden;

`ifdef FORMAL
initial begin
assume(reset);
end
assume property($initstate || (in_run || out_done));
`endif
always @* begin
_d_ac = _q_ac;
_d_i = _q_i;
_d_ret = _q_ret;
_d_index = _q_index;
// _always_pre
(* full_case *)
case (_q_index)
0: begin
// _top
_d_ac = {{15{1'b0}},_w_num[15+:1]};
_d_ret = {_w_num[0+:15],1'b0};
_d_index = 1;
end
1: begin
// __while__block_1
if (_q_i!=16) begin
// __block_2
// __block_4
if (_w_diff[16+:1]==0) begin
// __block_5
// __block_7
_d_ac = {_w_diff[0+:15],_q_ret[15+:1]};
_d_ret = {_q_ret[0+:15],1'b1};
// __block_8
end else begin
// __block_6
// __block_9
_d_ac = {_q_ac[0+:15],_q_ret[15+:1]};
_d_ret = {_q_ret[0+:15],1'b0};
// __block_10
end
// __block_11
_d_i = _q_i+1;
// __block_12
_d_index = 1;
end else begin
_d_index = 2;
end
end
2: begin
// __block_3
_d_index = 3;
end
3: begin // end of 
end
default: begin 
_d_index = {2{1'bx}};
`ifdef FORMAL
assume(0);
`endif
 end
endcase
// _always_post
end

always @(posedge clock) begin
_q_ac <= _d_ac;
_q_i <= (reset | ~in_run) ? 0 : _d_i;
_q_ret <= (reset | ~in_run) ? 0 : _d_ret;
_q_index <= reset ? 3 : ( ~in_run ? 0 : _d_index);
end

endmodule
module M_main (
out_leds,
in_run,
out_done,
reset,
out_clock,
clock
);
output  [7:0] out_leds;
input in_run;
output out_done;
input reset;
output out_clock;
input clock;
assign out_clock = clock;
wire signed [15:0] _w_div0_ret;
wire _w_div0_done;
wire signed [15:0] _c_num;
assign _c_num = 20043;
wire signed [15:0] _c_den;
assign _c_den = 41;
reg signed [15:0] _t_result;

reg  [7:0] _d_leds;
reg  [7:0] _q_leds;
reg signed [15:0] _d_div0_inum,_q_div0_inum;
reg signed [15:0] _d_div0_iden,_q_div0_iden;
reg  [1:0] _d_index,_q_index = 3;
reg  _autorun = 0;
reg  _div0_run = 0;
assign out_leds = _q_leds;
assign out_done = (_q_index == 3) & _autorun;
M_div16__div0 div0 (
.in_inum(_q_div0_inum),
.in_iden(_q_div0_iden),
.out_ret(_w_div0_ret),
.out_done(_w_div0_done),
.in_run(_div0_run),
.reset(reset),
.clock(clock));



`ifdef FORMAL
initial begin
assume(reset);
end
assume property($initstate || (out_done));
`endif
always @* begin
_d_leds = _q_leds;
_d_div0_inum = _q_div0_inum;
_d_div0_iden = _q_div0_iden;
_d_index = _q_index;
_div0_run = 1;
_t_result = 0;
// _always_pre
(* full_case *)
case (_q_index)
0: begin
// _top
_d_div0_inum = _c_num;
_d_div0_iden = _c_den;
_div0_run = 0;
_d_index = 1;
end
1: begin
// __block_1
if (_w_div0_done == 1) begin
_d_index = 2;
end else begin
_d_index = 1;
end
end
2: begin
// __block_2
_t_result = _w_div0_ret;
$display("%d / %d = %d",_c_num,_c_den,_t_result);
_d_leds = _t_result[0+:8];
_d_index = 3;
end
3: begin // end of 
end
default: begin 
_d_index = {2{1'bx}};
`ifdef FORMAL
assume(0);
`endif
 end
endcase
// _always_post
end

always @(posedge clock) begin
_q_leds <= _d_leds;
_q_index <= reset ? 3 : ( ~_autorun ? 0 : _d_index);
_autorun <= reset ? 0 : 1;
_q_div0_inum <= _d_div0_inum;
_q_div0_iden <= _d_div0_iden;
end

endmodule
module M_main (
out_leds,
in_run,
out_done,
reset,
out_clock,
clock
);
output  [7:0] out_leds;
input in_run;
output out_done;
input reset;
output out_clock;
input clock;
assign out_clock = clock;

reg  [7:0] _d_cnt;
reg  [7:0] _q_cnt;
reg  [7:0] _d_leds;
reg  [7:0] _q_leds;
reg  [1:0] _d_index,_q_index = 3;
reg  _autorun = 0;
assign out_leds = _q_leds;
assign out_done = (_q_index == 3) & _autorun;



`ifdef FORMAL
initial begin
assume(reset);
end
assume property($initstate || (out_done));
`endif
always @* begin
_d_cnt = _q_cnt;
_d_leds = _q_leds;
_d_index = _q_index;
// _always_pre
_d_leds = _q_cnt[(8)-(8)+:8];
(* full_case *)
case (_q_index)
0: begin
// _top
_d_index = 1;
end
1: begin
// __while__block_1
if (1) begin
// __block_2
// __block_4
_d_cnt = _q_cnt+1;
// __block_5
_d_index = 1;
end else begin
_d_index = 2;
end
end
2: begin
// __block_3
_d_index = 3;
end
3: begin // end of 
end
default: begin 
_d_index = {2{1'bx}};
`ifdef FORMAL
assume(0);
`endif
 end
endcase
// _always_post
end

always @(posedge clock) begin
_q_cnt <= (reset) ? 0 : _d_cnt;
_q_leds <= _d_leds;
_q_index <= reset ? 3 : ( ~_autorun ? 0 : _d_index);
_autorun <= reset ? 0 : 1;
end

endmodule
module clk_gate (output gated_clk, input free_clk, func_en, pwr_en, gating_override);

   assign gated_clk = free_clk;
endmodule
module core #(
    parameter RESET_VECTOR = 32'h8000_0000
) (

`ifdef USE_POWER_PINS
    inout vccd1,	// User area 1 1.8V supply
    inout vssd1,	// User area 1 digital ground
`endif

    input clk,
    input reset,

    input meip,

    // Memory interface
    output ext_valid,
    output ext_instruction,
    input ext_ready,
    output [31:0] ext_address,
    output [31:0] ext_write_data,
    output [3:0] ext_write_strobe,
    input [31:0] ext_read_data
);

pipeline #(
    .RESET_VECTOR(RESET_VECTOR)
) core_pipeline (
    `ifdef USE_POWER_PINS
    .vccd1(vccd1),	// User area 1 1.8V supply
    .vssd1(vssd1),	// User area 1 digital ground
    `endif
    .clk(clk),
    .reset(reset),

    .meip(meip),

    .fetch_data(fetch_data),
    .mem_load_data(mem_load_data),
    .fetch_ready(fetch_ready),
    .mem_ready(mem_ready),

    .fetch_address(fetch_address),
    .mem_address(mem_address),
    .mem_store_data(mem_store_data),
    .mem_size(mem_size),
    .mem_signed(mem_signed),
    .mem_load(mem_load),
    .mem_store(mem_store)
);

wire [31:0] fetch_data;
wire [31:0] fetch_address;
wire fetch_ready;

wire [31:0] mem_load_data;
wire [31:0] mem_address;
wire [31:0] mem_store_data;
wire [1:0] mem_size;
wire mem_signed;
wire mem_load;
wire mem_store;
wire mem_ready;

busio core_busio (
    /* .clk(clk), */
    `ifdef USE_POWER_PINS
    .vccd1(vccd1),	// User area 1 1.8V supply
    .vssd1(vssd1),	// User area 1 digital ground
    `endif
    .ext_valid(ext_valid),
    .ext_instruction(ext_instruction),
    .ext_ready(ext_ready),
    .ext_address(ext_address),
    .ext_write_data(ext_write_data),
    .ext_write_strobe(ext_write_strobe),
    .ext_read_data(ext_read_data),

    .fetch_address(fetch_address),
    .fetch_data(fetch_data),
    .fetch_ready(fetch_ready),

    .mem_load_data(mem_load_data),
    .mem_ready(mem_ready),
    .mem_address(mem_address),
    .mem_store_data(mem_store_data),
    .mem_size(mem_size),
    .mem_signed(mem_signed),
    .mem_load(mem_load),
    .mem_store(mem_store)
);

endmodule
module user_project_wrapper #(
    parameter BITS = 32
) (
`ifdef USE_POWER_PINS
    inout vdda1,	// User area 1 3.3V supply
    inout vdda2,	// User area 2 3.3V supply
    inout vssa1,	// User area 1 analog ground
    inout vssa2,	// User area 2 analog ground
    inout vccd1,	// User area 1 1.8V supply
    inout vccd2,	// User area 2 1.8v supply
    inout vssd1,	// User area 1 digital ground
    inout vssd2,	// User area 2 digital ground
`endif

    // Wishbone Slave ports (WB MI A)
    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 wbs_ack_o,
    output [31:0] wbs_dat_o,

    // Logic Analyzer Signals
    input  [127:0] la_data_in,
    output [127:0] la_data_out,
    input  [127:0] la_oenb,

    // IOs
    input  [`MPRJ_IO_PADS-1:0] io_in,
    output [`MPRJ_IO_PADS-1:0] io_out,
    output [`MPRJ_IO_PADS-1:0] io_oeb,

    // Analog (direct connection to GPIO pad---use with caution)
    // Note that analog I/O is not available on the 7 lowest-numbered
    // GPIO pads, and so the analog_io indexing is offset from the
    // GPIO indexing by 7 (also upper 2 GPIOs do not have analog_io).
    inout [`MPRJ_IO_PADS-10:0] analog_io,

    // Independent clock (on independent integer divider)
    input   user_clock2,

    // User maskable interrupt signals
    output [2:0] user_irq
);

/*--------------------------------------*/
/* User project is instantiated  here   */
/*--------------------------------------*/

core my_core (
`ifdef USE_POWER_PINS
    .vccd1(vccd1), // User area 1 1.8V power
    .vssd1(vssd1), // User area 1 digital ground
`endif

    .clk(wb_clk_i),
    .reset(wb_rst_i),
    .meip(user_irq[0]), // Assuming user_irq[0] is MEIP (Machine External Interrupt Pending)

    // Memory interface (connected to Wishbone)
    .ext_valid(wbs_cyc_i & wbs_stb_i),  // External Valid signal asserted when Wishbone cycle and strobe are high
    .ext_instruction(wbs_we_i),  // Assuming ext_instruction is equivalent to Wishbone write-enable
    .ext_ready(wbs_ack_o),       // Assuming ext_ready is equivalent to Wishbone acknowledge
    .ext_address(wbs_adr_i),
    .ext_write_data(wbs_dat_i),
    .ext_write_strobe(wbs_sel_i),
    .ext_read_data(wbs_dat_o)
);

/*--------------------------------------*/
/* Unused signals are tied off here    */
/*--------------------------------------*/

// IOs
assign io_out = {`MPRJ_IO_PADS{1'b0}}; // Unused I/Os are tied off to ground
assign io_oeb = {`MPRJ_IO_PADS{1'b1}}; // Unused I/Os are tied off to ground

// IRQ
assign user_irq = 3'b000; // Unused

// LA
assign la_data_out = 128'h0; // Unused

endmodule
module user_proj_example #(
    parameter BITS = 32
)(
`ifdef USE_POWER_PINS
    inout vccd1,	// User area 1 1.8V supply
    inout vssd1,	// User area 1 digital ground
`endif

    // Wishbone Slave ports (WB MI A)
    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 wbs_ack_o,
    output [31:0] wbs_dat_o,

    // Logic Analyzer Signals
    input  [127:0] la_data_in,
    output [127:0] la_data_out,
    input  [127:0] la_oenb,

    // IOs
    input  [15:0] io_in,
    output [15:0] io_out,
    output [15:0] io_oeb,

    // IRQ
    output [2:0] irq
);
    wire clk;
    wire rst;

    wire [15:0] io_in;
    wire [15:0] io_out;
    wire [15:0] io_oeb;

    wire [15:0] rdata; 
    wire [15:0] wdata;
    wire [15:0] count;

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

    // WB MI A
    assign valid = wbs_cyc_i && wbs_stb_i; 
    assign wstrb = wbs_sel_i & {4{wbs_we_i}};
    assign wbs_dat_o = rdata;
    assign wdata = wbs_dat_i[15:0];

    // IO
    assign io_out = count;
    assign io_oeb = {(15){rst}};

    // IRQ
    assign irq = 3'b000;	// Unused

    // LA
    assign la_data_out = {{(127-BITS){1'b0}}, count};
    // Assuming LA probes [63:32] are for controlling the count register  
    assign la_write = ~la_oenb[63:32] & ~{BITS{valid}};
    // Assuming LA probes [65:64] are for controlling the count clk & reset  
    assign clk = (~la_oenb[64]) ? la_data_in[64]: wb_clk_i;
    assign rst = (~la_oenb[65]) ? la_data_in[65]: wb_rst_i;

    counter #(
        .BITS(BITS)
    ) counter(
        .clk(clk),
        .reset(rst),
        .ready(wbs_ack_o),
        .valid(valid),
        .rdata(rdata),
        .wdata(wbs_dat_i),
        .wstrb(wstrb),
        .la_write(la_write),
        .la_input(la_data_in[63:32]),
        .count(count)
    );

endmodule
module counter #(
    parameter BITS = 32
)(
    input clk,
    input reset,
    input valid,
    input [3:0] wstrb,
    input [15:0] wdata,
    input [BITS-1:0] la_write,
    input [BITS-1:0] la_input,
    output ready,
    output [15:0] rdata,
    output [15:0] count
);
    reg ready;
    reg [15:0] count;
    reg [15:0] rdata;

    always @(posedge clk) begin
        if (reset) begin
            count <= 0;
            ready <= 0;
        end else begin
            ready <= 1'b0;
            if (~|la_write) begin
                count <= count + 1;
            end
            if (valid && !ready) begin
                ready <= 1'b1;
                rdata <= count;
                if (wstrb[0]) count[7:0]   <= wdata[7:0];
                if (wstrb[1]) count[15:8]  <= wdata[15:8];
            end else if (|la_write) begin
                count <= la_write & la_input;
            end
        end
    end

endmodule
module user_project_wrapper #(
    parameter BITS = 32
) (
`ifdef USE_POWER_PINS 
    inout vdda1,	// User area 1 3.3V supply
    inout vdda2,	// User area 2 3.3V supply
    inout vssa1,	// User area 1 analog ground
    inout vssa2,	// User area 2 analog ground
    inout vccd1,	// User area 1 1.8V supply
    inout vccd2,	// User area 2 1.8v supply
    inout vssd1,	// User area 1 digital ground
    inout vssd2,	// User area 2 digital ground
`endif
    // Wishbone Slave ports (WB MI A)
    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 wbs_ack_o,
    output [31:0] wbs_dat_o,

    // Logic Analyzer Signals
    input  [127:0] la_data_in,
    output [127:0] la_data_out,
    input  [127:0] la_oenb,

    // IOs
    input  [`MPRJ_IO_PADS-1:0] io_in,
    output [`MPRJ_IO_PADS-1:0] io_out,
    output [`MPRJ_IO_PADS-1:0] io_oeb,

    // Analog (direct connection to GPIO pad---use with caution)
    // Note that analog I/O is not available on the 7 lowest-numbered
    // GPIO pads, and so the analog_io indexing is offset from the
    // GPIO indexing by 7 (also upper 2 GPIOs do not have analog_io).
    inout [`MPRJ_IO_PADS-10:0] analog_io,

    // Independent clock (on independent integer divider)
    input   user_clock2,

    // User maskable interrupt signals
    output [2:0] user_irq
);

/*--------------------------------------*/
/* User project is instantiated  here   */
/*--------------------------------------*/

core my_core (
    `ifdef USE_POWER_PINS
    .vccd1(vccd1), // User area 1 1.8V power
    .vssd1(vssd1), // User area 1 digital ground
    `endif
    .clk(wb_clk_i),
    .reset(wb_rst_i),
    .meip(user_irq[0]), // Assuming user_irq[0] is MEIP (Machine External Interrupt Pending)
    // Memory interface (connected to Wishbone)
    .ext_valid(wbs_stb_i),  // External Valid signal asserted when Wishbone cycle and strobe are high
    .ext_instruction(wbs_we_i),  // Assuming ext_instruction is equivalent to Wishbone write-enable
    .ext_ready(wbs_ack_o),       // Assuming ext_ready is equivalent to Wishbone acknowledge
    .ext_address(wbs_adr_i),
    .ext_write_data(wbs_dat_i),
    .ext_write_strobe(wbs_sel_i),
    .ext_read_data(wbs_dat_o)
);

/*--------------------------------------*/
/* Unused signals are tied off here    */
/*--------------------------------------*/


endmodule
module user_project_wrapper (user_clock2,
    wb_clk_i,
    wb_rst_i,
    wbs_ack_o,
    wbs_cyc_i,
    wbs_stb_i,
    wbs_we_i,
    analog_io,
    io_in,
    io_oeb,
    io_out,
    la_data_in,
    la_data_out,
    la_oenb,
    user_irq,
    wbs_adr_i,
    wbs_dat_i,
    wbs_dat_o,
    wbs_sel_i);
 input user_clock2;
 input wb_clk_i;
 input wb_rst_i;
 output wbs_ack_o;
 input wbs_cyc_i;
 input wbs_stb_i;
 input wbs_we_i;
 inout [28:0] analog_io;
 input [37:0] io_in;
 output [37:0] io_oeb;
 output [37:0] io_out;
 input [127:0] la_data_in;
 output [127:0] la_data_out;
 input [127:0] la_oenb;
 output [2:0] user_irq;
 input [31:0] wbs_adr_i;
 input [31:0] wbs_dat_i;
 output [31:0] wbs_dat_o;
 input [3:0] wbs_sel_i;


 core my_core (.clk(wb_clk_i),
    .ext_instruction(wbs_we_i),
    .ext_ready(wbs_ack_o),
    .ext_valid(wbs_stb_i),
    .meip(user_irq[0]),
    .reset(wb_rst_i),
    .ext_address({wbs_adr_i[31],
    wbs_adr_i[30],
    wbs_adr_i[29],
    wbs_adr_i[28],
    wbs_adr_i[27],
    wbs_adr_i[26],
    wbs_adr_i[25],
    wbs_adr_i[24],
    wbs_adr_i[23],
    wbs_adr_i[22],
    wbs_adr_i[21],
    wbs_adr_i[20],
    wbs_adr_i[19],
    wbs_adr_i[18],
    wbs_adr_i[17],
    wbs_adr_i[16],
    wbs_adr_i[15],
    wbs_adr_i[14],
    wbs_adr_i[13],
    wbs_adr_i[12],
    wbs_adr_i[11],
    wbs_adr_i[10],
    wbs_adr_i[9],
    wbs_adr_i[8],
    wbs_adr_i[7],
    wbs_adr_i[6],
    wbs_adr_i[5],
    wbs_adr_i[4],
    wbs_adr_i[3],
    wbs_adr_i[2],
    wbs_adr_i[1],
    wbs_adr_i[0]}),
    .ext_read_data({wbs_dat_o[31],
    wbs_dat_o[30],
    wbs_dat_o[29],
    wbs_dat_o[28],
    wbs_dat_o[27],
    wbs_dat_o[26],
    wbs_dat_o[25],
    wbs_dat_o[24],
    wbs_dat_o[23],
    wbs_dat_o[22],
    wbs_dat_o[21],
    wbs_dat_o[20],
    wbs_dat_o[19],
    wbs_dat_o[18],
    wbs_dat_o[17],
    wbs_dat_o[16],
    wbs_dat_o[15],
    wbs_dat_o[14],
    wbs_dat_o[13],
    wbs_dat_o[12],
    wbs_dat_o[11],
    wbs_dat_o[10],
    wbs_dat_o[9],
    wbs_dat_o[8],
    wbs_dat_o[7],
    wbs_dat_o[6],
    wbs_dat_o[5],
    wbs_dat_o[4],
    wbs_dat_o[3],
    wbs_dat_o[2],
    wbs_dat_o[1],
    wbs_dat_o[0]}),
    .ext_write_data({wbs_dat_i[31],
    wbs_dat_i[30],
    wbs_dat_i[29],
    wbs_dat_i[28],
    wbs_dat_i[27],
    wbs_dat_i[26],
    wbs_dat_i[25],
    wbs_dat_i[24],
    wbs_dat_i[23],
    wbs_dat_i[22],
    wbs_dat_i[21],
    wbs_dat_i[20],
    wbs_dat_i[19],
    wbs_dat_i[18],
    wbs_dat_i[17],
    wbs_dat_i[16],
    wbs_dat_i[15],
    wbs_dat_i[14],
    wbs_dat_i[13],
    wbs_dat_i[12],
    wbs_dat_i[11],
    wbs_dat_i[10],
    wbs_dat_i[9],
    wbs_dat_i[8],
    wbs_dat_i[7],
    wbs_dat_i[6],
    wbs_dat_i[5],
    wbs_dat_i[4],
    wbs_dat_i[3],
    wbs_dat_i[2],
    wbs_dat_i[1],
    wbs_dat_i[0]}),
    .ext_write_strobe({wbs_sel_i[3],
    wbs_sel_i[2],
    wbs_sel_i[1],
    wbs_sel_i[0]}));
endmodule
module user_project_wrapper (user_clock2,
    vccd1,
    vccd2,
    vdda1,
    vdda2,
    vssa1,
    vssa2,
    vssd1,
    vssd2,
    wb_clk_i,
    wb_rst_i,
    wbs_ack_o,
    wbs_cyc_i,
    wbs_stb_i,
    wbs_we_i,
    analog_io,
    io_in,
    io_oeb,
    io_out,
    la_data_in,
    la_data_out,
    la_oenb,
    user_irq,
    wbs_adr_i,
    wbs_dat_i,
    wbs_dat_o,
    wbs_sel_i);
 input user_clock2;
 input vccd1;
 input vccd2;
 input vdda1;
 input vdda2;
 input vssa1;
 input vssa2;
 input vssd1;
 input vssd2;
 input wb_clk_i;
 input wb_rst_i;
 output wbs_ack_o;
 input wbs_cyc_i;
 input wbs_stb_i;
 input wbs_we_i;
 inout [28:0] analog_io;
 input [37:0] io_in;
 output [37:0] io_oeb;
 output [37:0] io_out;
 input [127:0] la_data_in;
 output [127:0] la_data_out;
 input [127:0] la_oenb;
 output [2:0] user_irq;
 input [31:0] wbs_adr_i;
 input [31:0] wbs_dat_i;
 output [31:0] wbs_dat_o;
 input [3:0] wbs_sel_i;


 core my_core (.clk(wb_clk_i),
    .ext_instruction(wbs_we_i),
    .ext_ready(wbs_ack_o),
    .ext_valid(wbs_stb_i),
    .meip(user_irq[0]),
    .reset(wb_rst_i),
    .vccd1(vccd1),
    .vssd1(vssd1),
    .ext_address({wbs_adr_i[31],
    wbs_adr_i[30],
    wbs_adr_i[29],
    wbs_adr_i[28],
    wbs_adr_i[27],
    wbs_adr_i[26],
    wbs_adr_i[25],
    wbs_adr_i[24],
    wbs_adr_i[23],
    wbs_adr_i[22],
    wbs_adr_i[21],
    wbs_adr_i[20],
    wbs_adr_i[19],
    wbs_adr_i[18],
    wbs_adr_i[17],
    wbs_adr_i[16],
    wbs_adr_i[15],
    wbs_adr_i[14],
    wbs_adr_i[13],
    wbs_adr_i[12],
    wbs_adr_i[11],
    wbs_adr_i[10],
    wbs_adr_i[9],
    wbs_adr_i[8],
    wbs_adr_i[7],
    wbs_adr_i[6],
    wbs_adr_i[5],
    wbs_adr_i[4],
    wbs_adr_i[3],
    wbs_adr_i[2],
    wbs_adr_i[1],
    wbs_adr_i[0]}),
    .ext_read_data({wbs_dat_o[31],
    wbs_dat_o[30],
    wbs_dat_o[29],
    wbs_dat_o[28],
    wbs_dat_o[27],
    wbs_dat_o[26],
    wbs_dat_o[25],
    wbs_dat_o[24],
    wbs_dat_o[23],
    wbs_dat_o[22],
    wbs_dat_o[21],
    wbs_dat_o[20],
    wbs_dat_o[19],
    wbs_dat_o[18],
    wbs_dat_o[17],
    wbs_dat_o[16],
    wbs_dat_o[15],
    wbs_dat_o[14],
    wbs_dat_o[13],
    wbs_dat_o[12],
    wbs_dat_o[11],
    wbs_dat_o[10],
    wbs_dat_o[9],
    wbs_dat_o[8],
    wbs_dat_o[7],
    wbs_dat_o[6],
    wbs_dat_o[5],
    wbs_dat_o[4],
    wbs_dat_o[3],
    wbs_dat_o[2],
    wbs_dat_o[1],
    wbs_dat_o[0]}),
    .ext_write_data({wbs_dat_i[31],
    wbs_dat_i[30],
    wbs_dat_i[29],
    wbs_dat_i[28],
    wbs_dat_i[27],
    wbs_dat_i[26],
    wbs_dat_i[25],
    wbs_dat_i[24],
    wbs_dat_i[23],
    wbs_dat_i[22],
    wbs_dat_i[21],
    wbs_dat_i[20],
    wbs_dat_i[19],
    wbs_dat_i[18],
    wbs_dat_i[17],
    wbs_dat_i[16],
    wbs_dat_i[15],
    wbs_dat_i[14],
    wbs_dat_i[13],
    wbs_dat_i[12],
    wbs_dat_i[11],
    wbs_dat_i[10],
    wbs_dat_i[9],
    wbs_dat_i[8],
    wbs_dat_i[7],
    wbs_dat_i[6],
    wbs_dat_i[5],
    wbs_dat_i[4],
    wbs_dat_i[3],
    wbs_dat_i[2],
    wbs_dat_i[1],
    wbs_dat_i[0]}),
    .ext_write_strobe({wbs_sel_i[3],
    wbs_sel_i[2],
    wbs_sel_i[1],
    wbs_sel_i[0]}));
endmodule
module busio (
    `ifdef USE_POWER_PINS
    inout vccd1,	// User area 1 1.8V supply
    inout vssd1,	// User area 1 digital ground
    `endif
    /* input clk, */
    
    // External interface
    output ext_valid,
    output ext_instruction,
    input ext_ready,
    output [31:0] ext_address,
    output [31:0] ext_write_data,
    output reg [3:0] ext_write_strobe,
    input [31:0] ext_read_data,

    // Internal interface
    input [31:0] fetch_address,
    output [31:0] fetch_data,
    output fetch_ready,

    output reg [31:0] mem_load_data,
    output mem_ready,
    input [31:0] mem_address,
    input [31:0] mem_store_data,
    input [1:0] mem_size,
    input mem_signed,
    input mem_load,
    input mem_store
);



// Compute ext_valid
assign ext_valid = 1;

// Compute ext_instruction
assign ext_instruction = mem_load || mem_store ? 0 : 1;
// Compute ext_address using a continuous assignment

assign ext_address = (mem_load || mem_store) ? (mem_address & 32'hffff_fffc) : (fetch_address & 32'hffff_fffc);

// Compute ext_write_data using a continuous assignment
assign ext_write_data = mem_store ? (mem_store_data << (8 * mem_address[1:0])) : 0;

always @(*) begin
    if (!mem_store)
        ext_write_strobe = 4'b0000;
    else if (mem_size == 2'b00)
        ext_write_strobe = 4'b0001 << mem_address[1:0];
    else if (mem_size == 2'b01)
        ext_write_strobe = 4'b0011 << mem_address[1:0];
    else if (mem_size == 2'b10)
        ext_write_strobe = 4'b1111;
    else
        ext_write_strobe = 4'b0000;
end
// Fetch and memory interface ready signals
assign fetch_ready = ext_ready && ext_instruction;
assign mem_ready = ext_ready && !ext_instruction;

// Fetch data
assign fetch_data = ext_read_data;

// Compute mem_load_data
wire [31:0] tmp_load_data = ext_read_data >> (8 * mem_address[1:0]);

always @(*) begin
    if (mem_size == 2'b00) 
        mem_load_data = mem_signed && tmp_load_data[7] ? {{24{tmp_load_data[7]}}, tmp_load_data[7:0]} : {24'b0, tmp_load_data[7:0]};
    else if (mem_size == 2'b01) 
        mem_load_data = mem_signed && tmp_load_data[15] ? {{16{tmp_load_data[15]}}, tmp_load_data[15:0]} : {16'b0, tmp_load_data[15:0]};
    else if (mem_size == 2'b10)
        mem_load_data = tmp_load_data;
    else
        mem_load_data = 32'b0;
end

endmodule