dakies/OSS_Verilog huggingface dataset:
module fm_cmn_bfifo (
  clk_core,
  rst_x,
  i_wstrobe,
  i_dt,
  o_full,
  i_renable,
  o_dt,
  o_empty,
  o_dnum
);

// set default parameters
parameter P_WIDTH = 32;
parameter P_RANGE = 8;
parameter P_DEPTH = 1 << P_RANGE;
////////////////////////////
// I/O definition
////////////////////////////
input         clk_core;       // system clock
input         rst_x;          // system reset
input         i_wstrobe;      // write strobe
input  [P_WIDTH-1:0] i_dt;      // write data
output        o_full;         // write data full
input         i_renable;      // read enable
output [P_WIDTH-1:0] o_dt;      // read data
output        o_empty;        // read data empty
output [P_RANGE:0] o_dnum;      // written data number

/////////////////////////
//  Register definition
/////////////////////////
reg [P_RANGE-1:0] r_write_counter;
reg [P_RANGE-1:0] r_read_counter;
reg [P_RANGE:0]   r_status;
reg               r_sel;
/////////////////////////
//  wire definition
/////////////////////////
wire             o_full;
wire [P_WIDTH-1:0] o_dt;
wire [P_WIDTH-1:0] w_dto;
wire [P_WIDTH-1:0] w_dto_th;
wire [1:0]       w_status;
wire             w_we;
wire             w_re;
wire [P_RANGE-1:0] w_read_counter_inc;
wire [P_RANGE-1:0] w_read_counter;
/////////////////////////
//  assign statement
/////////////////////////
assign o_full  = (r_status == P_DEPTH);
assign o_empty = (r_status == 0);
assign o_dnum = r_status;
assign o_dt = (r_sel) ? w_dto_th : w_dto;

assign w_read_counter_inc = r_read_counter + 1'b1;
assign w_read_counter = (w_re) ? w_read_counter_inc : r_read_counter;
assign w_we = !o_full & i_wstrobe;
assign w_re = i_renable & !o_empty;
assign w_status = {w_re,w_we};
////////////////////////
// always statement
///////////////////////
  // write side
  always @(posedge clk_core or negedge rst_x) begin
    if (~rst_x) begin
      r_write_counter <= 'd0;
    end else begin
      if (w_we) begin
        r_write_counter <= r_write_counter + 1'b1;
      end
    end
  end

  // read side
  always @(posedge clk_core or negedge rst_x) begin
    if (~rst_x) begin
      r_read_counter <= 'd0;
    end else begin
      if (w_re) begin
        r_read_counter <= w_read_counter_inc;
      end
    end
  end

  // ram output select
  always @(posedge clk_core or negedge rst_x) begin
    if (~rst_x) begin
        r_sel <= 1'b0;
    end else begin
        r_sel <= (r_write_counter == w_read_counter) ? 1'b1 : 1'b0;
    end
  end

  // status counter
  always @(posedge clk_core or negedge rst_x) begin
    if (~rst_x) begin
      r_status <= 'd0;
    end else begin
      case (w_status)
        2'b01:  r_status <= r_status + 1'b1; // write
        2'b10:  r_status <= r_status - 1'b1; // read
        default:  r_status <= r_status;      // nothing to do 
      endcase
    end
  end

///////////////////
// module instance
///////////////////
    fm_cmn_bram_01 #(P_WIDTH, P_RANGE) bram_00 (
        .clk(clk_core),
        .we(w_we),
        .a(r_write_counter),
        .dpra(w_read_counter),
        .di(i_dt),
        .spo(w_dto_th),
        .dpo(w_dto)
    );
endmodule
module fm_fifo (
  clk_core,
  rst_x,
  i_wstrobe,
  i_dt,
  o_full,
  i_renable,
  o_dt,
  o_empty,
  o_dnum
);

// set default parameters
parameter P_WIDTH = 32;
parameter P_RANGE = 2;
parameter P_DEPTH = 1 << P_RANGE;
parameter P_CLEAR = "FALSE";
   
////////////////////////////
// I/O definition
////////////////////////////
input         clk_core;       // system clock
input         rst_x;          // system reset
input         i_wstrobe;      // write strobe
input  [P_WIDTH-1:0] i_dt;    // write data
output        o_full;         // write data full
input         i_renable;      // read enable
output [P_WIDTH-1:0] o_dt;    // read data
output        o_empty;        // read data empty
output [P_RANGE:0] o_dnum;    // written data number

/////////////////////////
//  Register definition
/////////////////////////
reg [P_RANGE-1:0] rs_write_counter;
reg [P_RANGE-1:0] rs_read_counter;
// data registers
reg [P_WIDTH-1:0] rs_data_buffer[0:P_DEPTH-1];
reg [P_RANGE:0] rs_status;
/////////////////////////
//  wire definition
/////////////////////////
wire             o_full;
wire             o_empty;
wire [P_WIDTH-1:0] o_dt;
wire [1:0]       w_status;
wire             w_we;
wire             w_re;
/////////////////////////
//  assign statement
/////////////////////////
assign o_full  = (rs_status == P_DEPTH);
assign o_empty = (rs_status == 0);
assign o_dt = rs_data_buffer[rs_read_counter];
assign o_dnum = rs_status;
assign w_we = !o_full & i_wstrobe;
assign w_re = i_renable & !o_empty;
assign w_status = {w_re,w_we};
////////////////////////
// always statement
///////////////////////
  // write side
  always @(posedge clk_core or negedge rst_x) begin
    if (~rst_x) begin
      rs_write_counter <= 'd0;
    end else begin
      if (w_we) begin
        rs_write_counter <= rs_write_counter + 1'b1;
      end
    end
  end

generate
  if (P_CLEAR == "TRUE") begin
    integer i;
    always @(posedge clk_core or negedge rst_x) begin
      if (~rst_x) begin
        for(i=0;i<P_DEPTH;i=i+1) rs_data_buffer[i] <= 'd0;
      end else begin
        if (w_we) begin
          rs_data_buffer[rs_write_counter] <= i_dt;
        end
      end
    end
  end else begin
    always @(posedge clk_core) begin
      if (w_we) begin
        rs_data_buffer[rs_write_counter] <= i_dt;
      end
    end
  end
endgenerate   

  // read side
  always @(posedge clk_core or negedge rst_x) begin
    if (~rst_x) begin
      rs_read_counter <= 'd0;
    end else begin
      if (w_re) begin
        rs_read_counter <= rs_read_counter + 1'b1;
      end
    end
  end
  // status counter
  always @(posedge clk_core or negedge rst_x) begin
    if (~rst_x) begin
      rs_status <= 'd0;
    end else begin
      case (w_status)
        2'b01:  rs_status <= rs_status + 1'b1; // write
        2'b10:  rs_status <= rs_status - 1'b1; // read
        default:  rs_status <= rs_status;      // nothing to do 
      endcase
    end
  end

endmodule
module fm_3d_fcnv (
  i_f32,
  o_f22
);

////////////////////////////
// I/O definition
////////////////////////////
    input  [31:0] i_f32;
    output [21:0] o_f22;

////////////////////////////
// assign
////////////////////////////
    assign o_f22 = f_f32_to_f22(i_f32);
////////////////////////////
// function
////////////////////////////
    function [21:0] f_f32_to_f22;
        input [31:0] f32;
        reg s;
        reg [7:0]  e8;
        reg [8:0]  e8d;  // width sign bit
        reg [4:0]  e5;
        reg [23:0] m23;
        reg [14:0] m15;
        reg        carry;
        reg        zf;
        begin
            s = f32[31];
            e8 = f32[30:23];
            zf = (e8 == 8'h00);
            m23 = f32[22:0];
            {carry,m15} = m23[22:8] + m23[7];
            e8d = e8 - 112 + carry;  // -127+15 + carry
            if (zf|e8d[8]) begin
                e5 = 5'h0;
            end else begin
                e5 = e8d[4:0];
            end
            f_f32_to_f22 = {s,e5,!(zf|e8d[8]),m15};
        end
    endfunction

endmodule
module fm_3d_f22_to_z (
    i_a,
    o_b
);

///////////////////////////////////////////
//  port definition
///////////////////////////////////////////
    input  [21:0] i_a;          // input s1, e5, f1.15
    output [15:0] o_b;          // unsigned integer
///////////////////////////////////////////
//  wire definition
///////////////////////////////////////////
    // intermidiate wire
    wire [4:0]  w_exp;
    wire [15:0] w_fraction;

///////////////////////////////////////////
//  assign statement
///////////////////////////////////////////
    assign w_exp  = i_a[20:16];
    assign w_fraction = i_a[15:0];

    assign o_b = f_ftoi(w_exp, w_fraction);
///////////////////////////////////////////
//  function statement
///////////////////////////////////////////
    function [15:0] f_ftoi;
        input [4:0]  exp;
        input [15:0] frac;
        begin
            if (&exp[4:3]) begin  // over value
                f_ftoi = 16'hffff;
            end else begin
                case (exp[4:0])
                    5'h7:  f_ftoi = {15'b0,frac[15]};    // bias 0
                    5'h8:  f_ftoi = {14'b0,frac[15:14]};
                    5'h9:  f_ftoi = {13'b0,frac[15:13]};
                    5'ha:  f_ftoi = {12'b0,frac[15:12]};
                    5'hb:  f_ftoi = {11'b0,frac[15:11]};
                    5'hc:  f_ftoi = {10'b0,frac[15:10]};
                    5'hd:  f_ftoi = {9'b0,frac[15:9]};
                    5'he:  f_ftoi = {8'b0,frac[15:8]};
                    5'hf:  f_ftoi = {7'b0,frac[15:7]};
                    5'h10: f_ftoi = {6'b0,frac[15:6]};
                    5'h11: f_ftoi = {5'b0,frac[15:5]};
                    5'h12: f_ftoi = {4'b0,frac[15:4]};
                    5'h13: f_ftoi = {3'b0,frac[15:3]};
                    5'h14: f_ftoi = {2'b0,frac[15:2]};
                    5'h15: f_ftoi = {1'b0,frac[15:1]};
                    5'h16: f_ftoi = frac[15:0];
                    5'h17: f_ftoi = 16'hffff;
                    default: f_ftoi = 16'h0;
                endcase
            end
        end
    endfunction

endmodule
module fm_3d_ru_span_step_core (
    clk_core,
    rst_x,
    i_en,
    i_valid,
    i_kind,
    i_end_flag,
    i_start_p,
    i_end_p,
    i_delta_t,
    o_valid,
    o_kind,
    o_end_flag,
    o_start_p,
    o_step_p
);

////////////////////////////
// I/O definition
////////////////////////////
    input         clk_core;
    input         rst_x;
    input         i_en;
    input         i_valid;
    input  [3:0]  i_kind;
    input         i_end_flag;
    input  [21:0] i_start_p;
    input  [21:0] i_end_p;
    input  [21:0] i_delta_t;
    output        o_valid;
    output [3:0]  o_kind;
    output        o_end_flag;
    output [21:0] o_start_p;
    output [21:0] o_step_p;
////////////////////////////
// wire
////////////////////////////
    wire  [21:0]  w_end_p;
    wire  [21:0]  w_start_p;
    wire  [21:0]  w_delta_p;
////////////////////////////
// assign
////////////////////////////
////////////////////////////
// module instance
////////////////////////////
    // adder (end_p - start_p)
    fm_3d_fadd fadd (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a(i_end_p),
        .i_b(i_start_p),
        .i_adsb(1'b1),
        .o_c(w_delta_p)
    );

    // delta_p * delta_t (not necessary to add delay to delta_t, t is static)
    fm_3d_fmul mul_delta_tp (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a(w_delta_p),
        .i_b(i_delta_t),
        .o_c(o_step_p)
    );
    // delay adjust for o_start_p
    fm_3d_delay #(22,6) delay_p (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_data(i_start_p),
        .o_data(o_start_p)
    );

    // delay adjust for valid
    fm_3d_delay #(1,6) delay_valid (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_data(i_valid),
        .o_data(o_valid)
    );

    fm_3d_delay #(1,6) delay_end_flag (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_data(i_end_flag),
        .o_data(o_end_flag)
    );

    fm_3d_delay #(4,6) delay_kind (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_data(i_kind),
        .o_data(o_kind)
    );

endmodule
module fm_3d_ru_span_delta (
    clk_core,
    rst_x,
    // span parameters
    i_start,
    o_finish,
    i_x_l,
    i_x_r,
    // generated parameters
    o_delta_t,
    o_delta_a
);
////////////////////////////
// parameter
////////////////////////////
    parameter P_SETUP0   = 3'h0;
    parameter P_SETUP1   = 3'h1;
    parameter P_SETUP2   = 3'h2;
    parameter P_SETUP3   = 3'h3;
    parameter P_SETUP4   = 3'h4;
    parameter P_SETUP5   = 3'h5;
    parameter P_SETUP6   = 3'h6;
////////////////////////////
// I/O definition
////////////////////////////
    input         clk_core;
    input         rst_x;
    // span parameters
    input         i_start;
    output        o_finish;
    input  [20:0] i_x_l;
    input  [20:0] i_x_r;
    // generated parameters
    output [21:0] o_delta_t;
    output [21:0] o_delta_a;

////////////////////////////
// reg
////////////////////////////
    reg    [2:0]  r_state;
    reg    [21:0] r_delta_t;
    reg           r_is_delta_x_zero;
////////////////////////////
// wire
////////////////////////////
    wire  [21:0]  w_adder_out;
    wire  [21:0]  w_recip_out;

    wire          w_set_delta_t;
    wire          w_set_dx_zero;
    wire  [21:0]  w_05;
    wire  [21:0]  w_00;
    wire          w_is_zero;
////////////////////////////
// assign
////////////////////////////
    assign w_05 = 22'he8000;
    assign w_00 = 22'h00000;
    assign w_set_dx_zero = (r_state == P_SETUP3);
    assign w_is_zero = (w_adder_out == w_00);  // compare delta_x and zero
    assign w_set_delta_t = (r_state == P_SETUP5);
    // port connection
    assign o_delta_t = r_delta_t;
    assign o_delta_a = (r_is_delta_x_zero) ? w_00 : w_05;
    assign o_finish = (r_state == P_SETUP6);
////////////////////////////
// always
////////////////////////////
    always @(posedge clk_core or negedge rst_x) begin
        if (~rst_x) begin
            r_state <= P_SETUP0;
        end else begin
            case (r_state)
                P_SETUP0: if (i_start) r_state <= P_SETUP1;
                P_SETUP1: r_state <= P_SETUP2;
                P_SETUP2: r_state <= P_SETUP3;
                P_SETUP3: r_state <= P_SETUP4;
                P_SETUP4: r_state <= P_SETUP5;
                P_SETUP5: r_state <= P_SETUP6;
                P_SETUP6: r_state <= P_SETUP0;  // delta_t register store cycle
            endcase
        end
    end

    always @(posedge clk_core) begin
        if (w_set_delta_t) r_delta_t <= w_recip_out;
    end

    always @(posedge clk_core or negedge rst_x) begin
        if (~rst_x) begin
            r_is_delta_x_zero <= 1'b0;
        end else begin
            if (w_set_dx_zero) r_is_delta_x_zero <= w_is_zero;
        end
    end

////////////////////////////
// module instance
////////////////////////////
    // adder
    fm_3d_fadd fadd (
        .clk_core(clk_core),
        .i_en(1'b1),
        .i_a({1'b0,i_x_r}),
        .i_b({1'b0,i_x_l}),
        .i_adsb(1'b1),
        .o_c(w_adder_out)
    );
    // 1/x
    fm_3d_frcp frcp (
        .clk_core(clk_core),
        .i_en(1'b1),
        .i_a(w_adder_out),
        .o_c(w_recip_out)
    );

endmodule
module fm_3d_delay_r (
    clk_core,
    rst_x,
    i_en,
    i_data,
    o_data
);

////////////////////////////
// parameter
////////////////////////////
    parameter P_WIDTH     = 8;
    parameter P_NUM_DELAY = 8;
////////////////////////////
// I/O definition
////////////////////////////
    input                clk_core;
    input                rst_x;
    input                i_en;
    input  [P_WIDTH-1:0] i_data;
    output [P_WIDTH-1:0] o_data;


////////////////////////////
// reg
////////////////////////////
    reg   [P_WIDTH-1:0] r_delay[0:P_NUM_DELAY-1];

////////////////////////////
// assign
////////////////////////////
    // in/out port connection
    assign o_data = r_delay[P_NUM_DELAY-1];

////////////////////////////
// always
////////////////////////////
    always @(posedge clk_core) begin
        if (i_en) r_delay[0] <= i_data;
    end

    // delay register connection
    integer i;
    always @(posedge clk_core or negedge rst_x) begin
        if (!rst_x) begin
            if ( P_NUM_DELAY > 1 ) begin
                for ( i = 1; i < P_NUM_DELAY; i = i + 1) begin
                    r_delay[i] <= 0;
                end
            end
        end else begin
            if ( P_NUM_DELAY > 1 ) begin
                for ( i = 1; i < P_NUM_DELAY; i = i + 1) begin
                    if (i_en) r_delay[i] <= r_delay[i-1];
                end
            end
        end
    end

endmodule
module fm_3d_cu_bselect (
    clk_core,
    rst_x,
    // system bus
    i_req_sys,
    i_wr_sys,
    i_adrs_sys,
    o_ack_sys,
    i_be_sys,
    i_dbw_sys,
    o_strr_sys,
    o_dbr_sys,
    // DMA bus
    i_req_dma,
    i_adrs_dma,
    i_dbw_dma,
    // internal bus side
    o_req,
    o_wr,
    o_adrs,
    i_ack,
    o_be,
    o_dbw,
    i_strr,
    i_dbr
);

////////////////////////////
// I/O definition
////////////////////////////
    input         clk_core;
    input         rst_x;
    // system bus
    input         i_req_sys;
    input         i_wr_sys;
    input  [21:0] i_adrs_sys;
    output        o_ack_sys;
    input  [3:0]  i_be_sys;
    input  [31:0] i_dbw_sys;
    output        o_strr_sys;
    output [31:0] o_dbr_sys;
    // DMA bus
    input         i_req_dma;
    input  [21:0] i_adrs_dma;
    input  [31:0] i_dbw_dma;
    // internal bus side
    output        o_req;
    output        o_wr;
    output [21:0] o_adrs;
    input         i_ack;
    output [3:0]  o_be;
    output [31:0] o_dbw;
    input         i_strr;
    input  [31:0] i_dbr;
/////////////////////////
//  register definition
/////////////////////////
    reg           r_req_sys;
    reg           r_wr_sys;
    reg    [21:0] r_adrs_sys;
    reg    [3:0]  r_be_sys;
    reg    [31:0] r_dbw_sys;
    // DMA bus
    reg           r_req_dma;
    reg    [21:0] r_adrs_dma;
    reg    [31:0] r_dbw_dma;
/////////////////////////
//  wire definition
/////////////////////////
    wire          w_ack;
/////////////////////////
//  assign statement
/////////////////////////
    assign o_req = r_req_sys | r_req_dma;
    assign o_wr = (r_req_dma) ? 1'b1 : r_wr_sys;
    assign o_adrs = (r_req_dma) ? r_adrs_dma : r_adrs_sys;
    assign o_be = (r_req_dma) ? 4'hf : r_be_sys;
    assign o_dbw = (r_req_dma) ? r_dbw_dma : r_dbw_sys;
    assign o_strr_sys = i_strr;
    assign o_dbr_sys = i_dbr;

    assign w_ack = (r_req_dma) ? 1'b0 : i_ack;
    assign o_ack_sys = w_ack;
/////////////////////////
//  always statement
/////////////////////////
    always @(posedge clk_core or negedge rst_x) begin
        if (~rst_x) begin
            r_req_sys <= 1'b0;
            r_req_dma <= 1'b0;
        end else begin
            if (w_ack) r_req_sys <= 1'b0;
            else r_req_sys <= i_req_sys; 

            r_req_dma <= i_req_dma;
        end
    end

    always @(posedge clk_core) begin
        r_wr_sys <= i_wr_sys;
        r_adrs_sys <= i_adrs_sys;
        r_be_sys <= i_be_sys;
        r_dbw_sys <= i_dbw_sys;
        r_adrs_dma <= i_adrs_dma;
        r_dbw_dma <= i_dbw_dma;
    end


endmodule
module fm_3d_tu_etc_rom (
  clk_core,
  i_a,
  o_c
);

////////////////////////////
// I/O definition
////////////////////////////
    input         clk_core;
    input  [4:0]  i_a;  // table 3bits, index 2bits
    output [8:0]  o_c;

////////////////////////////
// reg
////////////////////////////
    reg    [8:0]  r_c;
////////////////////////////
// assign
////////////////////////////
    assign o_c = r_c;
///////////////////////////////////////////
//  always statement
///////////////////////////////////////////
    always @(posedge clk_core) begin
        case (i_a)
            5'b000_00:   r_c <= 9'h002;  // table0, index0 =  2
            5'b000_01:   r_c <= 9'h008;  // table0, index1 =  8
            5'b000_10:   r_c <= 9'h1fe;  // table0, index2 = -2
            5'b000_11:   r_c <= 9'h1f8;  // table0, index3 = -8
            5'b001_00:   r_c <= 9'h005;  // table1, index0 =  5
            5'b001_01:   r_c <= 9'h011;  // table1, index1 =  17
            5'b001_10:   r_c <= 9'h1fb;  // table1, index2 = -5
            5'b001_11:   r_c <= 9'h1ef;  // table1, index3 = -17
            5'b010_00:   r_c <= 9'h009;  // table2, index0 =  9
            5'b010_01:   r_c <= 9'h01d;  // table2, index1 =  29
            5'b010_10:   r_c <= 9'h1f7;  // table2, index2 = -9
            5'b010_11:   r_c <= 9'h1e3;  // table2, index3 = -29
            5'b011_00:   r_c <= 9'h00d;  // table3, index0 =  13
            5'b011_01:   r_c <= 9'h02a;  // table3, index1 =  42
            5'b011_10:   r_c <= 9'h1f3;  // table3, index2 = -13
            5'b011_11:   r_c <= 9'h1d6;  // table3, index3 = -42
            5'b100_00:   r_c <= 9'h012;  // table4, index0 =  18
            5'b100_01:   r_c <= 9'h03c;  // table4, index1 =  60
            5'b100_10:   r_c <= 9'h1ee;  // table4, index2 = -18
            5'b100_11:   r_c <= 9'h1c4;  // table4, index3 = -60
            5'b101_00:   r_c <= 9'h018;  // table5, index0 =  24
            5'b101_01:   r_c <= 9'h050;  // table5, index1 =  80
            5'b101_10:   r_c <= 9'h1e8;  // table5, index2 = -24
            5'b101_11:   r_c <= 9'h1b0;  // table5, index3 = -80
            5'b110_00:   r_c <= 9'h021;  // table6, index0 =  33
            5'b110_01:   r_c <= 9'h06a;  // table6, index1 =  106
            5'b110_10:   r_c <= 9'h1df;  // table6, index2 = -33
            5'b110_11:   r_c <= 9'h196;  // table6, index3 = -106
            5'b111_00:   r_c <= 9'h02f;  // table7, index0 =  47
            5'b111_01:   r_c <= 9'h0b7;  // table7, index1 =  183
            5'b111_10:   r_c <= 9'h1d1;  // table7, index2 = -47
            5'b111_11:   r_c <= 9'h149;  // table7, index3 = -183
            default: r_c <= 9'h000;
        endcase
    end


endmodule
module fm_3d_f22_to_ui_b (
    i_a,
    o_b
);

///////////////////////////////////////////
//  port definition
///////////////////////////////////////////
    input  [21:0] i_a;          // input s1, e5, f1.15
    output [15:0] o_b;          // unsigned integer
///////////////////////////////////////////
//  wire definition
///////////////////////////////////////////
    // intermidiate wire
    wire [4:0]  w_exp;
    wire [15:0] w_fraction;

///////////////////////////////////////////
//  assign statement
///////////////////////////////////////////
    assign w_exp  = i_a[20:16];
    assign w_fraction = i_a[15:0];

    assign o_b = f_ftoi(w_exp, w_fraction);
///////////////////////////////////////////
//  function statement
///////////////////////////////////////////
    function [15:0] f_ftoi;
        input [4:0]  exp;
        input [15:0] frac;
        begin
            case (exp)
                5'd19: f_ftoi = {15'b0,frac[15]};    // bias 0
                5'd20: f_ftoi = {14'b0,frac[15:14]};
                5'd21: f_ftoi = {13'b0,frac[15:13]};
                5'd22: f_ftoi = {12'b0,frac[15:12]};
                5'd23: f_ftoi = {11'b0,frac[15:11]};
                5'd24: f_ftoi = {10'b0,frac[15:10]};
                5'd25: f_ftoi = {9'b0,frac[15:9]};
                5'd26: f_ftoi = {8'b0,frac[15:8]};
                5'd27: f_ftoi = {7'b0,frac[15:7]};
                5'd28: f_ftoi = {6'b0,frac[15:6]};
                5'd29: f_ftoi = {5'b0,frac[15:5]};
                5'd30: f_ftoi = {4'b0,frac[15:4]};
                5'd31: f_ftoi = {3'b0,frac[15:3]};
                default: f_ftoi = 16'h0;
            endcase
        end
    endfunction

endmodule
module fm_3d_f22_floor (
    i_a,
    o_b
);

///////////////////////////////////////////
//  port definition
///////////////////////////////////////////
    input  [20:0] i_a;          // input e5, f1.15
    output [20:0] o_b;          
///////////////////////////////////////////
//  wire definition
///////////////////////////////////////////
    // intermidiate wire
    wire [4:0]  w_exp;
    wire [15:0] w_fraction;
    wire [15:0] w_fraction_out;

///////////////////////////////////////////
//  assign statement
///////////////////////////////////////////
    assign w_exp  = i_a[20:16];
    assign w_fraction = i_a[15:0];

    assign o_b = {w_exp, w_fraction_out};
    assign w_fraction_out = f_floor(w_exp, w_fraction);
///////////////////////////////////////////
//  function statement
///////////////////////////////////////////
    function [15:0] f_floor;
        input [4:0]  exp;
        input [15:0] frac;
        begin
            case (exp[4:0])
                5'hf:  f_floor = {frac[15],15'h0};
                5'h10: f_floor = {frac[15:14],14'h0};
                5'h11: f_floor = {frac[15:13],13'h0};
                5'h12: f_floor = {frac[15:12],12'h0};
                5'h13: f_floor = {frac[15:11],11'h0};
                5'h14: f_floor = {frac[15:10],10'h0};
                5'h15: f_floor = {frac[15:9],9'h0};
                5'h16: f_floor = {frac[15:8],8'h0};
                5'h17: f_floor = {frac[15:7],7'h0};
                5'h18: f_floor = {frac[15:6],6'h0};
                5'h19: f_floor = {frac[15:5],5'h0};
                5'h1a: f_floor = {frac[15:4],4'h0};
                5'h1b: f_floor = {frac[15:3],3'h0};
                5'h1c: f_floor = {frac[15:2],2'h0};
                5'h1d: f_floor = {frac[15:1],1'h0};
                5'h1e: f_floor = frac[15:0];
                default: f_floor = 16'h0;
            endcase
        end
    endfunction

endmodule
module fm_3d_f22_to_i8_2 (
  i_a,
  o_b
);

///////////////////////////////////////////
//  port definition
///////////////////////////////////////////
    input  [21:0] i_a;          // input s1, e5, f1.15
    output [7:0]  o_b;          // unsigned integer
///////////////////////////////////////////
//  wire definition
///////////////////////////////////////////
    // intermidiate wire
    wire        w_sign;
    wire [4:0]  w_exp;
    wire [15:0] w_fraction;

///////////////////////////////////////////
//  assign statement
///////////////////////////////////////////
    assign w_sign = i_a[21];
    assign w_exp  = i_a[20:16];
    assign w_fraction = i_a[15:0];

    assign o_b = f_ftoi(w_exp, w_fraction);
///////////////////////////////////////////
//  function statement
///////////////////////////////////////////
    function [7:0] f_ftoi;
        input [4:0]  exp;
        input [15:0] frac;
        begin
            case (exp)
                5'd15: f_ftoi = {7'b0,frac[15]};
                5'd16: f_ftoi = {6'b0,frac[15:14]};
                5'd17: f_ftoi = {5'b0,frac[15:13]};
                5'd18: f_ftoi = {4'b0,frac[15:12]};
                5'd19: f_ftoi = {3'b0,frac[15:11]};
                5'd20: f_ftoi = {2'b0,frac[15:10]};
                5'd21: f_ftoi = {1'b0,frac[15:9]};
                5'd22: f_ftoi = frac[15:8];
                5'd23: f_ftoi = 8'd255;  // overflow
                default: f_ftoi = 8'h0;  // including zero
            endcase
        end
    endfunction

endmodule
module fm_3d_mu_cache_tag (
    clk_core,
    rst_x,
    i_tw_valid,
    i_adrs_pre,  // for timing improvement
    i_adrs,
    i_tag_clear,
    o_hit,
    o_need_wb,
    o_entry,
    o_tag_adrs
);
`include "polyphony_params.v"
////////////////////////////
// Parameter definition
////////////////////////////
    //parameter P_ADRS_WIDTH  = 26;   // 21.5.4
    parameter P_ADRS_WIDTH  =  P_IB_TAG_ADDR_WIDTH+P_IB_CACHE_ENTRY_WIDTH;
    parameter P_ENTRY_RANGE = P_IB_CACHE_ENTRY_WIDTH;
    parameter P_ENTRY_DEPTH = 1 << P_ENTRY_RANGE;
    parameter P_TAG_RANGE   = P_ADRS_WIDTH - P_ENTRY_RANGE;
////////////////////////////
// I/O definition
////////////////////////////
    input         clk_core;
    input         rst_x;
    input         i_tw_valid;
    input  [P_ADRS_WIDTH-1:0]
                  i_adrs_pre;
    input  [P_ADRS_WIDTH-1:0]
                  i_adrs;
    input         i_tag_clear;
    output        o_hit;
    output        o_need_wb;
    output [P_ENTRY_RANGE-1:0]
                  o_entry;
    output [P_TAG_RANGE-1:0]
                  o_tag_adrs;

//////////////////////////////////
// wire 
//////////////////////////////////
    wire          w_tag_update;
    wire [P_ENTRY_RANGE-1:0]
                  w_update_number_pre;
    wire [P_ENTRY_RANGE-1:0]
                  w_update_number;
    wire          w_cmp;
    wire          w_valid;
    wire [P_ADRS_WIDTH-P_ENTRY_RANGE-1:0]
                  w_tag_adrs;
    wire [P_ADRS_WIDTH-P_ENTRY_RANGE-1:0]
                  w_new_adrs;
//////////////////////////////////
// reg
//////////////////////////////////
    reg  [P_ENTRY_DEPTH-1:0] r_valids;
//////////////////////////////////
// assign
//////////////////////////////////
    assign w_update_number_pre = i_adrs_pre[P_ENTRY_RANGE-1:0];
    assign w_update_number = i_adrs[P_ENTRY_RANGE-1:0];
    assign w_new_adrs = i_adrs[P_ADRS_WIDTH-1:P_ENTRY_RANGE];
    assign w_cmp = (w_tag_adrs == w_new_adrs);
    assign w_valid = r_valids[w_update_number];
    assign o_hit = (w_valid) ? w_cmp : 1'b0 ;
 
    assign w_tag_update = !o_hit & i_tw_valid;
    assign o_need_wb = w_valid;
    assign o_entry = w_update_number;
    assign o_tag_adrs = w_tag_adrs;
//////////////////////////////////
// always
//////////////////////////////////

    always @(posedge clk_core or negedge rst_x) begin
        if (~rst_x) begin
            // tag initial clear
            r_valids <= {P_ENTRY_DEPTH{1'b0}};
        end else begin
            if (i_tag_clear) begin
                r_valids <= {P_ENTRY_DEPTH{1'b0}};
            end
            if (w_tag_update) begin
                  r_valids[w_update_number] <= 1'b1;
            end
        end
    end

////////////////////////////
// module instance
////////////////////////////
    // not including valid bit
    fm_cmn_bram_01 #((P_ADRS_WIDTH-P_ENTRY_RANGE),P_ENTRY_RANGE) tag_bram (
        .clk(clk_core),
        .we(w_tag_update),
        .a(w_update_number),
        .dpra(w_update_number_pre),  // check address
        .di(w_new_adrs),
        .spo(),
        .dpo(w_tag_adrs)
    );

endmodule
module fm_3d_delay (
    clk_core,
    i_en,
    i_data,
    o_data
);

////////////////////////////
// parameter
////////////////////////////
    parameter P_WIDTH     = 8;
    parameter P_NUM_DELAY = 8;
////////////////////////////
// I/O definition
////////////////////////////
    input                clk_core;
    input                i_en;
    input  [P_WIDTH-1:0] i_data;
    output [P_WIDTH-1:0] o_data;

////////////////////////////
// reg
////////////////////////////
    reg   [P_WIDTH-1:0] r_delay[0:P_NUM_DELAY-1];

////////////////////////////
// assign
////////////////////////////
    // in/out port connection
    assign o_data = r_delay[P_NUM_DELAY-1];

////////////////////////////
// always
////////////////////////////
    always @(posedge clk_core) begin
        if (i_en) r_delay[0] <= i_data;
    end

    // delay register connection
    integer i;
    always @(posedge clk_core) begin
        if ( P_NUM_DELAY > 1 ) begin
            for ( i = 1; i < P_NUM_DELAY; i = i + 1) begin
                if (i_en) r_delay[i] <= r_delay[i-1];
            end
        end
    end

endmodule
module fm_3d_f22_to_i8 (
  clk_core,
  i_en,
  i_a,
  o_b
);

///////////////////////////////////////////
//  port definition
///////////////////////////////////////////
    input         clk_core;
    input         i_en;
    input  [21:0] i_a;          // input s1, e5, f1.15
    output [7:0]  o_b;          // unsigned integer
///////////////////////////////////////////
//  wire definition
///////////////////////////////////////////
    // intermidiate wire
    wire        w_sign;
    wire [4:0]  w_exp;
    wire [15:0] w_fraction;
    wire [21:0] w_255;
    wire [21:0] w_c;

///////////////////////////////////////////
//  assign statement
///////////////////////////////////////////
    assign  w_255 = 22'h16ff00;
    assign w_sign = w_c[21];
    assign w_exp  = w_c[20:16];
    assign w_fraction = w_c[15:0];

    assign o_b = f_ftoi(w_exp, w_fraction);
///////////////////////////////////////////
//  module instance
///////////////////////////////////////////
    fm_3d_fmul u_fmul_255 (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a(i_a),
        .i_b(w_255),
        .o_c(w_c)
    );

///////////////////////////////////////////
//  function statement
///////////////////////////////////////////
    function [7:0] f_ftoi;
        input [4:0]  exp;
        input [15:0] frac;
        begin
            case (exp)
                5'd15: f_ftoi = {7'b0,frac[15]};
                5'd16: f_ftoi = {6'b0,frac[15:14]};
                5'd17: f_ftoi = {5'b0,frac[15:14]};
                5'd18: f_ftoi = {4'b0,frac[15:12]};
                5'd19: f_ftoi = {3'b0,frac[15:11]};
                5'd20: f_ftoi = {2'b0,frac[15:10]};
                5'd21: f_ftoi = {1'b0,frac[15:9]};
                5'd22: f_ftoi = frac[15:8];
                5'd23: f_ftoi = 8'd255;  // overflow
                default: f_ftoi = 8'h0;  // including zero
            endcase
        end
    endfunction

endmodule
module fm_3d_mu_cif (
  clk_core,
  rst_x,
  // bus side port
  i_bstr,
  i_bdata,
  o_back,
  // internal port
  o_istr,
  o_idata,
  i_iack
);
parameter P_WIDTH = 30;

////////////////////////////
// I/O definitions
////////////////////////////
input         i_bstr;         // input strobe
input  [P_WIDTH-1:0]
              i_bdata;        // input data
output        o_back;         // output acknowledge

output        o_istr;         // output strobe
output [P_WIDTH-1:0]
              o_idata;        // output data
input         i_iack;         // input acknowledge

input         clk_core;            // system clock
input         rst_x;          // system reset

/////////////////////////
//  register definition
/////////////////////////
// input register
reg           r_bstr;
reg    [P_WIDTH-1:0]
              r_bdata;

/////////////////////////
//  wire definition
/////////////////////////
/////////////////////////
//  assign statement
/////////////////////////
assign o_istr = r_bstr;
assign o_idata = r_bdata;
assign o_back = i_iack;
/////////////////////////
//  always statement
/////////////////////////
always @(posedge clk_core or negedge rst_x) begin
  if (~rst_x) begin
    r_bstr <= 1'b0;
  end else begin
    if (i_iack) r_bstr <= i_bstr;
  end
end

always @(posedge clk_core) begin
  if (i_iack) r_bdata <= i_bdata;
end


endmodule
module fm_3d_interp (
  clk_core,
  i_en,
  i_a,
  i_b,
  i_t,
  o_c
);

////////////////////////////
// I/O definition
////////////////////////////
    input         clk_core;
    input         i_en;
    input  [21:0] i_a;
    input  [21:0] i_b;
    input  [21:0] i_t;
    output [21:0] o_c;          // result


///////////////////////////////////////////
//  wire 
///////////////////////////////////////////
    wire [21:0]  w_b_a_3z;
    wire [21:0]  w_a_3z;
    wire [21:0]  w_t_3z;
    wire [21:0]  w_abt_6z;
    wire [21:0]  w_a_6z;

////////////////////////////
// module instance
////////////////////////////

    // stage1-3

    // ib-ia
    fm_3d_fadd fadd_b_a (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a(i_b),
        .i_b(i_a),
        .i_adsb(1'b1),
        .o_c(w_b_a_3z)
    );

    fm_3d_delay #(22,3) delay_a (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_data(i_a),
        .o_data(w_a_3z)
    );

    fm_3d_delay #(22,3) delay_t (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_data(i_t),
        .o_data(w_t_3z)
    );

    // stage 4-6

    // (i_b-i_a)*t
    fm_3d_fmul fmul_t (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a(w_b_a_3z),
        .i_b(w_t_3z),
        .o_c(w_abt_6z)
    );

    fm_3d_delay #(22,3) delay_a_2 (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_data(w_a_3z),
        .o_data(w_a_6z)
    );

    // stage 6-9

    // i_a + (i_b-i_a) *t
    fm_3d_fadd fadd_ab (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a(w_a_6z),
        .i_b(w_abt_6z),
        .i_adsb(1'b0),
        .o_c(o_c)
    );

endmodule
module fm_3d_interp_e (
    clk_core,
    rst_x,
    i_en,
    i_wf,
    i_a,
    i_iwa,
    i_b,
    i_iwb,
    i_t,
    i_w,
    o_c
);

////////////////////////////
// I/O definition
////////////////////////////
    input         clk_core;
    input         rst_x;
    input         i_en;
    input         i_wf;
    input  [21:0] i_a;
    input  [21:0] i_iwa;
    input  [21:0] i_b;
    input  [21:0] i_iwb;
    input  [21:0] i_t;
    input  [21:0] i_w;
    output [21:0] o_c;          // result


///////////////////////////////////////////
//  wire 
///////////////////////////////////////////
    wire [21:0]  w_aiw;
    wire [21:0]  w_biw;

    wire [21:0]  w_aiw_s;
    wire [21:0]  w_biw_s;


    wire [21:0]  w_td;
    wire [21:0]  w_td_s;
    wire [21:0]  w_wd;

    wire [21:0]  w_wdd;
////////////////////////////
// assign
////////////////////////////
    assign w_aiw_s = (i_wf) ? w_aiw : i_a;
    assign w_biw_s = (i_wf) ? w_biw : i_b;
    assign w_td_s  = (i_wf) ? w_td : i_t;


////////////////////////////
// module instance
////////////////////////////

    // stage1-3

    fm_3d_fmul mul_aiw (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a(i_a),
        .i_b(i_iwa),
        .o_c(w_aiw)
    );

    fm_3d_fmul mul_biw (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a(i_b),
        .i_b(i_iwb),
        .o_c(w_biw)
    );

    fm_3d_delay #(22,3) delay_t (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_data(i_t),
        .o_data(w_td)
    );

    fm_3d_delay #(22,2) delay_w (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_data(i_w),
        .o_data(w_wd)
    );

    // stage4-12 (interpolate)

    fm_3d_interp interp (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a(w_aiw_s),
        .i_b(w_biw_s),
        .i_t(w_td_s),
        .o_c(o_c)
    );

endmodule
module fm_3d_mu_cache_mem (
    clk_core,
    i_we,
    i_adrs,
    i_adrs_pre,
    i_be,
    i_dt,
    o_dt,
    o_dt_pre
);
`include "polyphony_params.v"
////////////////////////////
// Parameter definition
////////////////////////////
    parameter P_RANGE = P_IB_CACHE_ENTRY_WIDTH+P_IB_CACHE_LINE_WIDTH;
    parameter P_DEPTH = 1 << P_RANGE;
////////////////////////////
// I/O definition
////////////////////////////
    input         clk_core;
    input         i_we;
    input  [P_RANGE-1:0]
                  i_adrs;
    input  [P_RANGE-1:0]
                  i_adrs_pre;
    input  [P_IB_DATA_WIDTH/8-1:0]
                  i_be;
    input  [P_IB_DATA_WIDTH-1:0]
                  i_dt;
    output [P_IB_DATA_WIDTH-1:0]
                  o_dt;
    output [P_IB_DATA_WIDTH-1:0]
                  o_dt_pre;

//////////////////////////////////
// wire 
//////////////////////////////////
    wire   [P_IB_BE_WIDTH/2-1:0]
                  w_we;
//////////////////////////////////
// assign
//////////////////////////////////
////////////////////////////
// module instance
////////////////////////////
    genvar gi;
    // per 16-bit byte enable
    generate for (gi=0;gi < P_IB_BE_WIDTH/2;gi=gi+1) begin
      assign w_we[gi] = i_we & (|i_be[gi*2+1:gi*2]);
      
      fm_cmn_bram_01 #(16, P_RANGE) bram (
        .clk(clk_core),
        .we(w_we[gi]),
        .a(i_adrs),
        .dpra(i_adrs_pre),
        .di(i_dt[(gi+1)*16-1:gi*16]),
        .spo(o_dt[(gi+1)*16-1:gi*16]),
        .dpo(o_dt_pre[(gi+1)*16-1:gi*16])
      );
    end
    endgenerate

endmodule
module fm_3d_f22_to_ui (
    i_a,
    o_b
);

///////////////////////////////////////////
//  port definition
///////////////////////////////////////////
    input  [21:0] i_a;          // input s1, e5, f1.15
    output [15:0] o_b;          // unsigned integer
///////////////////////////////////////////
//  wire definition
///////////////////////////////////////////
    // intermidiate wire
    wire [4:0]  w_exp;
    wire [15:0] w_fraction;

///////////////////////////////////////////
//  assign statement
///////////////////////////////////////////
    assign w_exp  = i_a[20:16];
    assign w_fraction = i_a[15:0];

    assign o_b = f_ftoi(w_exp, w_fraction);
///////////////////////////////////////////
//  function statement
///////////////////////////////////////////
    function [15:0] f_ftoi;
        input [4:0]  exp;
        input [15:0] frac;
        reg   [5:0]  ee;
        begin
            ee = exp - 4'd15;  // remove bias
            if (ee[5]) begin
                f_ftoi = 16'h0;
            end else begin
                case (ee[4:0])
                    5'd0:  f_ftoi = {15'b0,frac[15]};    // bias 0
                    5'd1:  f_ftoi = {14'b0,frac[15:14]};
                    5'd2:  f_ftoi = {13'b0,frac[15:13]};
                    5'd3:  f_ftoi = {12'b0,frac[15:12]};
                    5'd4:  f_ftoi = {11'b0,frac[15:11]};
                    5'd5:  f_ftoi = {10'b0,frac[15:10]};
                    5'd6:  f_ftoi = {9'b0,frac[15:9]};
                    5'd7:  f_ftoi = {8'b0,frac[15:8]};
                    5'd8:  f_ftoi = {7'b0,frac[15:7]};
                    5'd9:  f_ftoi = {6'b0,frac[15:6]};
                    5'd10: f_ftoi = {5'b0,frac[15:5]};
                    5'd11: f_ftoi = {4'b0,frac[15:4]};
                    5'd12: f_ftoi = {3'b0,frac[15:3]};
                    5'd13: f_ftoi = {2'b0,frac[15:2]};
                    5'd14: f_ftoi = {1'b0,frac[15:1]};
                    5'd15: f_ftoi = frac[15:0];
                    default: f_ftoi = 16'h0;
                endcase
            end
        end
    endfunction

endmodule
module fm_3d_ru_outline_step_core (
    clk_core,
    i_en,
    i_valid,
    i_kind,
    i_end_flag,
    i_start_p,
    i_end_p,
    i_start_iw,
    i_end_iw,
    i_delta_t,
    i_apply_iw,
    o_valid,
    o_kind,
    o_end_flag,
    o_start_p,
    o_step_p
);

////////////////////////////
// I/O definition
////////////////////////////
    input         clk_core;
    input         i_en;
    input         i_valid;
    input  [3:0]  i_kind;
    input         i_end_flag;
    input  [20:0] i_start_p;
    input  [20:0] i_end_p;
    input  [20:0] i_start_iw;
    input  [20:0] i_end_iw;
    input  [21:0] i_delta_t;
    input         i_apply_iw;
    output        o_valid;
    output [3:0]  o_kind;
    output        o_end_flag;
    output [20:0] o_start_p;
    output [21:0] o_step_p;
////////////////////////////
// wire
////////////////////////////
    wire  [21:0]  w_start_iw;
    wire  [21:0]  w_end_iw;
    wire  [21:0]  w_end_p;
    wire  [21:0]  w_start_p;
    wire  [21:0]  w_delta_p;
    wire  [21:0]  w_10;
////////////////////////////
// assign
////////////////////////////
    assign w_10 = {1'b0, 5'h0f, 16'h8000};
    assign w_start_iw = (i_apply_iw) ? {1'b0,i_start_iw} : w_10;
    assign w_end_iw = (i_apply_iw) ? {1'b0,i_end_iw} : w_10;
////////////////////////////
// module instance
////////////////////////////

    // end * iw
    fm_3d_fmul mul_end (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a({1'b0,i_end_p}),
        .i_b(w_end_iw),
        .o_c(w_end_p)
    );

    // start * iw
    fm_3d_fmul mul_start (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a({1'b0,i_start_p}),
        .i_b(w_start_iw),
        .o_c(w_start_p)
    );

    // adder (end_p - start_p)
    fm_3d_fadd fadd (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a(w_end_p),
        .i_b(w_start_p),
        .i_adsb(1'b1),
        .o_c(w_delta_p)
    );

    // delta_p * delta_t (not necessary to add delay to delta_t, t is static)
    fm_3d_fmul mul_delta_tp (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a(w_delta_p),
        .i_b(i_delta_t),
        .o_c(o_step_p)
    );
    // delay adjust for o_start_p
    fm_3d_delay #(21,6) delay_p (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_data(w_start_p[20:0]),
        .o_data(o_start_p)
    );

    // delay adjust for valid
    fm_3d_delay #(1,9) delay_valid (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_data(i_valid),
        .o_data(o_valid)
    );

    fm_3d_delay #(1,9) delay_end_flag (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_data(i_end_flag),
        .o_data(o_end_flag)
    );

    fm_3d_delay #(4,9) delay_kind (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_data(i_kind),
        .o_data(o_kind)
    );

endmodule
module fm_3d_interp_s (
    clk_core,
    rst_x,
    i_en,
    i_a,
    i_b,
    i_t,
    i_w,
    o_c
);

////////////////////////////
// I/O definition
////////////////////////////
    input         clk_core;
    input         rst_x;
    input         i_en;
    input  [21:0] i_a;
    input  [21:0] i_b;
    input  [21:0] i_t;
    input  [21:0] i_w;
    output [21:0] o_c;          // result


///////////////////////////////////////////
//  wire 
///////////////////////////////////////////
    wire [21:0]  w_wd;

    wire [21:0]  w_io;
////////////////////////////
// module instance
////////////////////////////

    // stage1-9 (interpolate)

    fm_3d_interp interp (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a(i_a),
        .i_b(i_b),
        .i_t(i_t),
        .o_c(w_io)
    );

    fm_3d_delay #(22,9) delay_wd (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_data(i_w),
        .o_data(w_wd)
    );

    // stage 10-12
    fm_3d_fmul mul_w (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a(w_io),
        .i_b(w_wd),
        .o_c(o_c)
    );

endmodule
module fm_3d_mu_dif (
  clk_core,
  rst_x,
  // bus side port
  i_bstr,
  i_bdata,
  o_back,
  // internal port
  o_istr,
  o_idata,
  i_iack
);

parameter P_WIDTH = 36;
////////////////////////////
// I/O definitions
////////////////////////////
input         i_bstr;         // input strobe
input  [P_WIDTH-1:0]
              i_bdata;        // input data (Write Data + BE)
output        o_back;         // output acknowledge

output        o_istr;         // output strobe
output [P_WIDTH-1:0]
              o_idata;        // output data
input         i_iack;         // input acknowledge

input         clk_core;            // system clock
input         rst_x;          // system reset

/////////////////////////
//  register definition
/////////////////////////
// input register
reg           r_bstr;
reg    [P_WIDTH-1:0]
              r_bdata;

/////////////////////////
//  wire definition
/////////////////////////
/////////////////////////
//  assign statement
/////////////////////////
assign o_istr = r_bstr;
assign o_idata = r_bdata;
assign o_back = i_iack;
/////////////////////////
//  always statement
/////////////////////////
always @(posedge clk_core or negedge rst_x) begin
  if (~rst_x) begin
    r_bstr <= 1'b0;
  end else begin
    if (i_iack) r_bstr <= i_bstr;
  end
end

always @(posedge clk_core) begin
  if (i_iack) r_bdata <= i_bdata;
end

endmodule
module fm_3d_imul8 (
    i_a,
    i_b,
    o_c
);

////////////////////////////
// I/O definition
////////////////////////////
    input  [7:0]  i_a;
    input  [7:0]  i_b;
    output [7:0]  o_c;

///////////////////////////////////////////
//  wire 
///////////////////////////////////////////
    wire   [15:0] w_m0;
    wire   [15:0] w_m1;
    wire   [8:0]  w_carry;
    wire   [7:0]  w_c;
///////////////////////////////////////////
//  assign
///////////////////////////////////////////
    assign w_m0 = i_a * i_b;
    //assign w_m1 = w_m0 + 8'd128;  // original code
    assign w_m1[6:0] = w_m0[6:0];
    assign w_m1[15:7] = w_m0[15:7] + 1'b1;
    assign w_carry = w_m1[7:0] + w_m1[15:8];
    assign w_c = w_m1[15:8] + w_carry[8];
    assign o_c = w_c;

endmodule
module fm_3d_ru_outline_edge_update (
    clk_core,
    rst_x,
    i_en,
    i_cur_p,
    i_step_p,
    i_delta_a,
    i_aa_mode,
    o_cur_p
);

////////////////////////////
// I/O definition
////////////////////////////
    input         clk_core;
    input         rst_x;
    input         i_en;
    input  [21:0] i_cur_p;
    input  [21:0] i_step_p;
    input  [21:0] i_delta_a;
    input         i_aa_mode;
    output [21:0] o_cur_p;
////////////////////////////
// wire
////////////////////////////
    wire  [21:0]  w_step_p;
    wire  [21:0]  w_cur_p;
    wire  [21:0]  w_step_pp;
    wire  [21:0]  w_cur_pp;
////////////////////////////
// assign
////////////////////////////
    assign w_step_pp = (i_aa_mode) ? w_step_p : i_step_p;
    assign w_cur_pp  = (i_aa_mode) ? w_cur_p : i_cur_p;
////////////////////////////
// module instance
////////////////////////////

    // step * delta
    fm_3d_fmul mul_delta (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a(i_step_p),
        .i_b(i_delta_a),
        .o_c(w_step_p)
    );

    // delay adjust for delta
    fm_3d_delay #(22,3) delay_p (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_data(i_cur_p),
        .o_data(w_cur_p)
    );

    // adder (end_p - start_p)
    fm_3d_fadd fadd (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a(w_cur_pp),
        .i_b(w_step_pp),
        .i_adsb(1'b0),
        .o_c(o_cur_p)
    );



endmodule