data/full_repos/permissive/174323821/hdl/sdram/jtframe_romrq.v
data/verilator_xmls/68a69d87-9182-419a-bce2-31f62085a00c.xml
module jtframe_romrq #(parameter
    SDRAMW  = 22,
    AW      = 18,
    DW      =  8,
    OKLATCH =  1,





    DOUBLE  =  0,

    LATCH   =  0
)(
    input               rst,
    input               clk,

    input               clr,
    input [SDRAMW-1:0]  offset,


    input [15:0]        din,
    input               din_ok,
    input               dst,
    input               we,
    output reg          req,
    output [SDRAMW-1:0] sdram_addr,


    input [AW-1:0]      addr,
    input               addr_ok,
    output              data_ok,
    output reg [DW-1:0] dout
);

reg [AW-1:0] addr_req;

reg [AW-1:0] cached_addr0, cached_addr1, addr_l;
reg [31:0]   cached_data0, cached_data1;
reg [1:0]    good, hitl;
reg          hit0, hit1;
reg          dend, double, cache_ok;
wire [AW-1:0] shifted;

assign sdram_addr = offset + { {SDRAMW-AW{1'b0}}, addr_req>>(DW==8)};
assign data_ok    = cache_ok && {hit1,hit0}==hitl && (hit1 || hit0);

always @(*) begin
    case(DW)
        8:  addr_req = {addr[AW-1:2],2'b0};
        16,32: addr_req = {addr[AW-1:1],1'b0};
    endcase


    hit0 = addr_req === cached_addr0 && good[0];
    hit1 = addr_req === cached_addr1 && good[1];
    req = (!(hit0 || hit1) && !we) && addr_ok;
end



always @(posedge clk, posedge rst) begin
    if( rst ) begin
        good         <= 0;
        cached_data0 <= 0;
        cached_data1 <= 0;
        cached_addr0 <= 0;
        cached_addr1 <= 0;
        cache_ok     <= 0;
        dend         <= 0;
        double       <= 0;
        hitl         <= 0;
    end else begin
        hitl <= { hit1, hit0 };
        if( clr ) good <= 0;
        if( req ) addr_l <= addr_req;
        if( we ) begin
            if( dst | (double&~dend) ) begin
                cached_data1 <= cached_data0;
                cached_addr1 <= cached_addr0;
                cached_data0[31:16] <= din;
                if( double )
                    cached_addr0[1] <= ~cached_addr0[1];
                else
                    cached_addr0 <= addr_l;
                good <= { good[0], 1'b1 };
                dend <= 1;
            end
            if( dend ) begin
                cached_data0[31:16] <= din;
                cached_data0[15: 0] <= cached_data0[31:16];
                if( !LATCH[0] && !DOUBLE[0] ) cache_ok<= 1;
                if( DOUBLE ) double <= ~double;
                dend <= 0;
            end
        end
        else begin
            cache_ok <= addr_ok && ( hit0 || hit1 );
            double   <= 0;
        end
    end
end




wire [31:0] data_mux = hit0 ? cached_data0 : cached_data1;
reg  [DW-1:0] preout;

generate
    if(DW==8) begin
        always @(*)
        case( addr[1:0] )
            2'd0: preout = data_mux[ 7: 0];
            2'd1: preout = data_mux[15: 8];
            2'd2: preout = data_mux[23:16];
            2'd3: preout = data_mux[31:24];
        endcase
    end else if(DW==16) begin
        always @(*)
        case( addr[0] )
                1'd0: preout = data_mux[15:0];
                1'd1: preout = data_mux[31:16];
        endcase
    end else always @(*) preout = data_mux;
endgenerate

generate
    if( LATCH==0 ) begin : data_latch
        always @(*) dout = preout;
    end else begin : no_data_latch
        always @(posedge clk) dout <= preout;
    end
endgenerate

`ifdef JTFRAME_SDRAM_STATS
jtframe_romrq_stats u_stats(
    .clk    ( clk       ),
    .rst    ( rst       ),
    .req    ( req       ),
    .we     ( we        ),
    .din_ok ( din_ok    ),
    .data_ok( data_ok   )
);
`endif

`ifdef SIMULATION
`ifndef VERILATOR
`ifndef JTFRAME_SIM_ROMRQ_NOCHECK
reg [AW-1:0] last_addr;
reg          waiting, last_req;

always @(posedge clk, posedge rst) begin
    if( rst ) begin
        waiting <= 0;
        last_req <= 0;
    end else begin
        last_req <= req;
        if( req && !last_req ) begin
            if( waiting ) begin
                $display("ERROR: %m new request without finishing the previous");
                $finish;
            end
            last_addr <= addr;
            waiting <= 1;
        end
        if( din_ok && we ) waiting <= 0;
        if( waiting && !addr_ok ) begin
            $display("ERROR: %m data request interrupted");
            $finish;
        end
        if( addr != last_addr && addr_ok) begin
            if( waiting ) begin
                $display("ERROR: %m address changed at time %t",$time);
                #40 $finish;
            end else waiting <= !hit0 && !hit1;
        end
    end
end
`endif
`endif
`endif

endmodule
module jtframe_romrq #(parameter
    SDRAMW  = 22,
    AW      = 18,
    DW      =  8,
    OKLATCH =  1,





    DOUBLE  =  0,

    LATCH   =  0
)(
    input               rst,
    input               clk,

    input               clr,
    input [SDRAMW-1:0]  offset,


    input [15:0]        din,
    input               din_ok,
    input               dst,
    input               we,
    output reg          req,
    output [SDRAMW-1:0] sdram_addr,


    input [AW-1:0]      addr,
    input               addr_ok,
    output              data_ok,
    output reg [DW-1:0] dout
);


reg [AW-1:0] addr_req;

reg [AW-1:0] cached_addr0, cached_addr1, addr_l;
reg [31:0]   cached_data0, cached_data1;
reg [1:0]    good, hitl;
reg          hit0, hit1;
reg          dend, double, cache_ok;
wire [AW-1:0] shifted;

assign sdram_addr = offset + { {SDRAMW-AW{1'b0}}, addr_req>>(DW==8)};
assign data_ok    = cache_ok && {hit1,hit0}==hitl && (hit1 || hit0);

always @(*) begin
    case(DW)
        8:  addr_req = {addr[AW-1:2],2'b0};
        16,32: addr_req = {addr[AW-1:1],1'b0};
    endcase


    hit0 = addr_req === cached_addr0 && good[0];
    hit1 = addr_req === cached_addr1 && good[1];
    req = (!(hit0 || hit1) && !we) && addr_ok;
end



always @(posedge clk, posedge rst) begin
    if( rst ) begin
        good         <= 0;
        cached_data0 <= 0;
        cached_data1 <= 0;
        cached_addr0 <= 0;
        cached_addr1 <= 0;
        cache_ok     <= 0;
        dend         <= 0;
        double       <= 0;
        hitl         <= 0;
    end else begin
        hitl <= { hit1, hit0 };
        if( clr ) good <= 0;
        if( req ) addr_l <= addr_req;
        if( we ) begin
            if( dst | (double&~dend) ) begin
                cached_data1 <= cached_data0;
                cached_addr1 <= cached_addr0;
                cached_data0[31:16] <= din;
                if( double )
                    cached_addr0[1] <= ~cached_addr0[1];
                else
                    cached_addr0 <= addr_l;
                good <= { good[0], 1'b1 };
                dend <= 1;
            end
            if( dend ) begin
                cached_data0[31:16] <= din;
                cached_data0[15: 0] <= cached_data0[31:16];
                if( !LATCH[0] && !DOUBLE[0] ) cache_ok<= 1;
                if( DOUBLE ) double <= ~double;
                dend <= 0;
            end
        end
        else begin
            cache_ok <= addr_ok && ( hit0 || hit1 );
            double   <= 0;
        end
    end
end




wire [31:0] data_mux = hit0 ? cached_data0 : cached_data1;
reg  [DW-1:0] preout;

generate
    if(DW==8) begin
        always @(*)
        case( addr[1:0] )
            2'd0: preout = data_mux[ 7: 0];
            2'd1: preout = data_mux[15: 8];
            2'd2: preout = data_mux[23:16];
            2'd3: preout = data_mux[31:24];
        endcase
    end else if(DW==16) begin
        always @(*)
        case( addr[0] )
                1'd0: preout = data_mux[15:0];
                1'd1: preout = data_mux[31:16];
        endcase
    end else always @(*) preout = data_mux;
endgenerate

generate
    if( LATCH==0 ) begin : data_latch
        always @(*) dout = preout;
    end else begin : no_data_latch
        always @(posedge clk) dout <= preout;
    end
endgenerate

`ifdef JTFRAME_SDRAM_STATS
jtframe_romrq_stats u_stats(
    .clk    ( clk       ),
    .rst    ( rst       ),
    .req    ( req       ),
    .we     ( we        ),
    .din_ok ( din_ok    ),
    .data_ok( data_ok   )
);
`endif

`ifdef SIMULATION
`ifndef VERILATOR
`ifndef JTFRAME_SIM_ROMRQ_NOCHECK
reg [AW-1:0] last_addr;
reg          waiting, last_req;

always @(posedge clk, posedge rst) begin
    if( rst ) begin
        waiting <= 0;
        last_req <= 0;
    end else begin
        last_req <= req;
        if( req && !last_req ) begin
            if( waiting ) begin
                $display("ERROR: %m new request without finishing the previous");
                $finish;
            end
            last_addr <= addr;
            waiting <= 1;
        end
        if( din_ok && we ) waiting <= 0;
        if( waiting && !addr_ok ) begin
            $display("ERROR: %m data request interrupted");
            $finish;
        end
        if( addr != last_addr && addr_ok) begin
            if( waiting ) begin
                $display("ERROR: %m address changed at time %t",$time);
                #40 $finish;
            end else waiting <= !hit0 && !hit1;
        end
    end
end
`endif
`endif
`endif

endmodule