data/full_repos/permissive/204736068/SoM/RTL/vision/src/blink_himax.sv
 line:128: before: "{"
1: b'%Error: data/full_repos/permissive/204736068/SoM/RTL/vision/src/blink_himax.sv:101: Cannot find file containing module: \'HSOSC\'\n    HSOSC #(.CLKHF_DIV("0b10")) u_hfosc (\n    ^~~~~\n        ... Looked in:\n             data/full_repos/permissive/204736068/SoM/RTL/vision/src,data/full_repos/permissive/204736068/HSOSC\n             data/full_repos/permissive/204736068/SoM/RTL/vision/src,data/full_repos/permissive/204736068/HSOSC.v\n             data/full_repos/permissive/204736068/SoM/RTL/vision/src,data/full_repos/permissive/204736068/HSOSC.sv\n             HSOSC\n             HSOSC.v\n             HSOSC.sv\n             obj_dir/HSOSC\n             obj_dir/HSOSC.v\n             obj_dir/HSOSC.sv\n%Error: data/full_repos/permissive/204736068/SoM/RTL/vision/src/blink_himax.sv:108: Cannot find file containing module: \'ice40_resetn\'\n    ice40_resetn u_reset_n (.clk(clk), .resetn(rst_n));\n    ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/204736068/SoM/RTL/vision/src/blink_himax.sv:208: Cannot find file containing module: \'lsc_i2cm_himax\'\n    lsc_i2cm_himax #(\n    ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/204736068/SoM/RTL/vision/src/blink_himax.sv:243: Cannot find file containing module: \'IOL_B\'\n    IOL_B\n    ^~~~~\n%Error: data/full_repos/permissive/204736068/SoM/RTL/vision/src/blink_himax.sv:286: Cannot find file containing module: \'IOL_B\'\n    IOL_B #(\n    ^~~~~\n%Error: data/full_repos/permissive/204736068/SoM/RTL/vision/src/blink_himax.sv:324: Cannot find file containing module: \'stream_dual_clock_fifo\'\n    stream_dual_clock_fifo #(.DW(8), .AW(4)) i_stream_dual_clock_fifo (\n    ^~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/204736068/SoM/RTL/vision/src/blink_himax.sv:373: Cannot find file containing module: \'ice40_spram_128kx8\'\n    ice40_spram_128kx8 i_ice40_spram_128kx8 (\n    ^~~~~~~~~~~~~~~~~~\n%Warning-WIDTH: data/full_repos/permissive/204736068/SoM/RTL/vision/src/blink_himax.sv:405: Operator ADD expects 18 bits on the RHS, but RHS\'s VARREF \'pixel_valid\' generates 1 bits.\n                                                                                          : ... In instance blink_himax\n                    num_pixels <= num_pixels + pixel_valid;  \n                                             ^\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Warning-WIDTH: data/full_repos/permissive/204736068/SoM/RTL/vision/src/blink_himax.sv:409: Operator ADD expects 17 bits on the RHS, but RHS\'s VARREF \'pixel_valid\' generates 1 bits.\n                                                                                          : ... In instance blink_himax\n                        ram_addr <= ram_addr + pixel_valid;\n                                             ^\n%Warning-WIDTH: data/full_repos/permissive/204736068/SoM/RTL/vision/src/blink_himax.sv:412: Operator SUB expects 18 bits on the RHS, but RHS\'s VARREF \'uart_tx_empty\' generates 1 bits.\n                                                                                          : ... In instance blink_himax\n                    num_pixels <= num_pixels - uart_tx_empty;  \n                                             ^\n%Warning-WIDTH: data/full_repos/permissive/204736068/SoM/RTL/vision/src/blink_himax.sv:413: Operator ADD expects 17 bits on the RHS, but RHS\'s VARREF \'uart_tx_empty\' generates 1 bits.\n                                                                                          : ... In instance blink_himax\n                    ram_addr   <= ram_addr + uart_tx_empty;\n                                           ^\n%Error: data/full_repos/permissive/204736068/SoM/RTL/vision/src/blink_himax.sv:425: Cannot find file containing module: \'lsc_uart\'\n    lsc_uart #(.PERIOD(UART_PERIOD)) u_lsc_uart (\n    ^~~~~~~~\n%Error: data/full_repos/permissive/204736068/SoM/RTL/vision/src/blink_himax.sv:464: Cannot find file containing module: \'RGB\'\n    RGB u_led_driver (\n    ^~~\n%Error: Exiting due to 9 error(s), 4 warning(s)\n'
module blink_himax (

    input  wire        uart_rx   ,
    output logic       uart_tx   ,

    output logic [2:0] gpio      ,
    output logic       host_intr ,

    inout  wire        i2c_scl   ,
    inout  wire        i2c_sda   ,
    output logic       sensor_clk,

    input  wire        px_clk    ,
    input  wire        px_fv     ,
    input  wire        px_lv     ,

    input  wire  [3:0] pxd       ,

    output logic       mic_clk   ,
    output logic       mic_ws    ,
    input  logic       mic_dout  ,

    output logic       sensor_led,
    output logic       led_red   ,
    output logic       led_green ,
    output logic       led_blue
);





    parameter UART_PERIOD = 'd26;

    parameter HIMAX_INIT_FILE = "ram256x16_himax_162x162.mem";

    parameter NUM_HIMAX_CMDS = 7'd80;

    logic red, green, blue;


    logic [7:0] uart_rx_data, uart_tx_data;
    logic       uart_rx_valid, uart_tx_valid;
    logic       uart_tx_empty;
    logic       load_fifo    ;


    logic       fifo_in_ready, fifo_out_ready;
    logic [7:0] o_fifo_data  ;
    logic       o_fifo_valid, o_fifo_ready;


    logic [ 7:0] pixel_data ;
    logic        pixel_valid, pixel_ready;
    logic        pixel_eof  ;
    logic [17:0] num_pixels ;

    logic clk  ;
    logic rst_n, rst;


    HSOSC #(.CLKHF_DIV("0b10")) u_hfosc (
        .CLKHFEN(1'b1),
        .CLKHFPU(1'b1),
        .CLKHF  (clk )
    );


    ice40_resetn u_reset_n (.clk(clk), .resetn(rst_n));
    assign rst = ~rst_n;


    logic [27:0] clk_divider;
    always @(posedge clk) begin
        if (rst)
            clk_divider <= 0;
        else
            clk_divider <= clk_divider + 1;
    end


    assign mic_clk = clk_divider[1];
    assign mic_ws  = clk_divider[1+$clog2(64)];


    logic        init, init_done;
    logic [19:0] timer;

    enum {
        S_POR,
        S_PROG,
        S_WAIT_INIT,
        S_WAIT_UART,
        S_WAIT_FRAME,
        S_WAIT_UART_TX,
        S_PAUSE_UART,
        S_XXX
    } s_state, s_next;

    always_ff @(posedge clk) begin
        if(rst) s_state <= S_POR;
        else s_state <= s_next;
    end

    always_comb begin
        s_next = S_XXX;
        case (s_state)
            S_POR          : if (&timer) s_next = S_PROG; else s_next = S_POR;
            S_PROG         : s_next = S_WAIT_INIT;
            S_WAIT_INIT    : if (init_done) s_next = S_WAIT_UART; else s_next = S_WAIT_INIT;
            S_WAIT_UART    : if (uart_rx_valid) s_next = S_WAIT_FRAME; else s_next = S_WAIT_UART;
            S_WAIT_FRAME   : if (pixel_eof) s_next = S_WAIT_UART_TX; else s_next = S_WAIT_FRAME;
            S_WAIT_UART_TX :
                begin
                    if (num_pixels == '0)
                        s_next = S_WAIT_UART;
                    else
                        if (~uart_tx_empty)
                            s_next = S_PAUSE_UART;
                    else
                        s_next = S_WAIT_UART_TX;
                end
            S_PAUSE_UART : if (uart_tx_empty) s_next = S_WAIT_UART_TX; else s_next = S_PAUSE_UART;
            S_XXX        : s_next = S_XXX;
        endcase
    end

    always_ff @(posedge clk) begin
        if(rst) begin
            timer <= '0;
            init  <= '0;
        end else begin
            init <= '0;

            case (s_state)
                S_POR        : timer <= timer + 'd1;
                S_PROG       : init <= '1;
                S_WAIT_INIT  : timer <= '0;
                S_WAIT_UART  : timer <= '0;
                S_WAIT_FRAME : ;
                S_WAIT_UART_TX, S_PAUSE_UART : ;
                S_XXX        : ;
            endcase
        end
    end







    always_ff @(posedge clk) begin
        if(rst) begin
            sensor_led <= 0;
        end else begin
            if (uart_rx_valid)
                sensor_led <= '1;
            else if (pixel_valid)
                sensor_led <= '0;
        end
    end





    logic w_scl_out, w_sda_out;
    lsc_i2cm_himax #(
        .NUM_CMD  (NUM_HIMAX_CMDS ),
        .INIT_FILE(HIMAX_INIT_FILE)
    ) u_lsc_i2cm_himax (
        .clk      (clk      ),
        .init     (init     ),
        .init_done(init_done),
        .scl_in   (i2c_scl  ),
        .sda_in   (i2c_sda  ),
        .scl_out  (w_scl_out),
        .sda_out  (w_sda_out),
        .resetn   (rst_n    )
    );

    assign i2c_scl = w_scl_out ? 1'bz : 1'b0;
    assign i2c_sda = w_sda_out ? 1'bz : 1'b0;



    assign sensor_clk = init_done ? 1'b0 : clk;







    logic [7:0] cam_data;
    logic [3:0] pxd_d   ;
    logic       hsync, vsync;
    logic [9:0] pxl_cnt ;
    logic       pxl_vld ;
    logic [3:0] pxd_n, pxd_p;


    IOL_B
        #(
            .LATCHIN ("NONE_DDR"),
            .DDROUT  ("NO")
        ) u_io_pxd[3:0] (
            .PADDI  (pxd[3:0]),
            .DO1    (1'b0),
            .DO0    (1'b0),
            .CE     (1'b1),
            .IOLTO  (1'b1),
            .HOLD   (1'b0),
            .INCLK  (px_clk),
            .OUTCLK (px_clk),
            .PADDO  (),
            .PADDT  (),
            .DI1    (pxd_n[3:0]),
            .DI0    (pxd_p[3:0])
        );

    logic px_fv_p;

    assign px_fv_p = px_fv;

    logic px_lv_p, px_lv_n;
    IOL_B #(
        .LATCHIN("NONE_DDR"),
        .DDROUT ("NO"      )
    ) u_io_lv (
        .PADDI (px_lv  ),
        .DO1   (1'b0   ),
        .DO0   (1'b0   ),
        .CE    (1'b1   ),
        .IOLTO (1'b1   ),
        .HOLD  (1'b0   ),
        .INCLK (px_clk ),
        .OUTCLK(px_clk ),
        .PADDO (       ),
        .PADDT (       ),
        .DI1   (px_lv_n),
        .DI0   (px_lv_p)
    );



    always_ff @(posedge px_clk) begin
        pxd_d    <= pxd_p;
        cam_data <= {pxd_d, pxd_p};
        hsync    <= px_lv_p;
        vsync    <= px_fv_p;
        if (px_lv_p == '0)
            pxl_cnt <= '0;
        else
            pxl_cnt <= pxl_cnt + 'd1;
    end

    assign pxl_vld = hsync && ~pxl_cnt[0];






    stream_dual_clock_fifo #(.DW(8), .AW(4)) i_stream_dual_clock_fifo (
        .wr_clk          (px_clk             ),
        .wr_rst          (rst                ),
        .stream_s_data_i (cam_data           ),
        .stream_s_valid_i(pxl_vld & load_fifo),
        .stream_s_ready_o(                   ),
        .rd_clk          (clk                ),
        .rd_rst          (rst                ),
        .stream_m_data_o (pixel_data         ),
        .stream_m_valid_o(pixel_valid        ),
        .stream_m_ready_i(pixel_ready        )
    );


    assign pixel_ready = '1;


    logic [1:0] vsync_d;
    logic       eof    ;
    always_ff @(posedge px_clk)
        vsync_d <= {vsync_d[0], vsync};

    assign eof = vsync_d[1] & ~vsync_d[0];


    logic [1:0] eof_d;
    always_ff @(posedge clk)
        eof_d <= {eof_d[0], eof};

    assign pixel_eof = ~eof_d[1] & eof_d[0];


    always_ff @(posedge clk) begin
        if(rst) begin
            load_fifo <= '0;
        end else begin
            if ((s_state == S_WAIT_UART) & uart_rx_valid)
                load_fifo <= '1;
            else if ((s_state == S_WAIT_FRAME) & eof)
                load_fifo <= '0;
        end
    end


    logic [16:0] ram_addr    ;
    logic        ram_cs, ram_wr_en;
    logic        ram_rd_valid;
    logic [ 7:0] ram_wr_data ;
    logic [ 7:0] ram_rd_data ;
    ice40_spram_128kx8 i_ice40_spram_128kx8 (
        .clk    (clk        ),
        .rst    (rst        ),
        .cs     (ram_cs     ),
        .addr   (ram_addr   ),
        .wr_en  (ram_wr_en  ),
        .wr_data(ram_wr_data),
        .rd_data(ram_rd_data)
    );


    assign ram_wr_en   = pixel_valid & (s_state == S_WAIT_FRAME);
    assign ram_cs      = (pixel_valid & (s_state == S_WAIT_FRAME) ) | (uart_tx_empty & (s_state == S_WAIT_UART_TX));
    assign ram_wr_data = pixel_data;

    always_ff @(posedge clk) begin
        if(rst) begin
            ram_addr   <= '0;
            num_pixels <= '0;
        end else begin


            ram_rd_valid <= ram_cs & ~ram_wr_en;





            case (s_state)
                S_POR, S_PROG, S_WAIT_INIT :;
                S_WAIT_UART  : ram_addr <= '0;
                S_WAIT_FRAME : begin
                    num_pixels <= num_pixels + pixel_valid;
                    if (eof)
                        ram_addr <= '0;
                    else
                        ram_addr <= ram_addr + pixel_valid;
                end
                S_WAIT_UART_TX : begin
                    num_pixels <= num_pixels - uart_tx_empty;
                    ram_addr   <= ram_addr + uart_tx_empty;
                end

                S_PAUSE_UART : ;
                S_XXX        : ;
            endcase
        end
    end

    assign uart_tx_valid = ram_rd_valid;
    assign uart_tx_data  = ram_rd_data;

    lsc_uart #(.PERIOD(UART_PERIOD)) u_lsc_uart (
        .ref_clk(clk          ),
        .clk    (clk          ),
        .resetn (~rst         ),
        
        .i_din  (uart_tx_data ),
        .i_valid(uart_tx_valid),
        .o_empty(uart_tx_empty),
        
        .o_dout (uart_rx_data ),
        .o_valid(uart_rx_valid),
        
        .i_rxd  (uart_rx      ),
        .o_txd  (uart_tx      )
    );







    logic duty_cycle;
    assign duty_cycle = '1;

    RGB u_led_driver (
        .CURREN  (1'b1     ),
        .RGBLEDEN(1'b1     ),
        .RGB0PWM (red      ),
        .RGB1PWM (green    ),
        .RGB2PWM (blue     ),
        .RGB0    (led_red  ),
        .RGB1    (led_green),
        .RGB2    (led_blue )
    );
    defparam u_led_driver.CURRENT_MODE = "1" ;
    defparam u_led_driver.RGB0_CURRENT = "0b000001";
    defparam u_led_driver.RGB1_CURRENT = "0b000001";
    defparam u_led_driver.RGB2_CURRENT = "0b000001";

    assign red   = ~clk_divider[22] && clk_divider[21] && duty_cycle;
    assign green = clk_divider[22] && ~clk_divider[21] && duty_cycle;
    assign blue  = clk_divider[22] && clk_divider[21] && duty_cycle;

    assign gpio[0]   = clk_divider[23];
    assign gpio[1]   = clk_divider[22];
    assign gpio[2]   = clk_divider[21];
    assign host_intr = clk_divider[20];

endmodule
module blink_himax (

    input  wire        uart_rx   ,
    output logic       uart_tx   ,

    output logic [2:0] gpio      ,
    output logic       host_intr ,

    inout  wire        i2c_scl   ,
    inout  wire        i2c_sda   ,
    output logic       sensor_clk,

    input  wire        px_clk    ,
    input  wire        px_fv     ,
    input  wire        px_lv     ,

    input  wire  [3:0] pxd       ,

    output logic       mic_clk   ,
    output logic       mic_ws    ,
    input  logic       mic_dout  ,

    output logic       sensor_led,
    output logic       led_red   ,
    output logic       led_green ,
    output logic       led_blue
);






    parameter UART_PERIOD = 'd26;

    parameter HIMAX_INIT_FILE = "ram256x16_himax_162x162.mem";

    parameter NUM_HIMAX_CMDS = 7'd80;

    logic red, green, blue;


    logic [7:0] uart_rx_data, uart_tx_data;
    logic       uart_rx_valid, uart_tx_valid;
    logic       uart_tx_empty;
    logic       load_fifo    ;


    logic       fifo_in_ready, fifo_out_ready;
    logic [7:0] o_fifo_data  ;
    logic       o_fifo_valid, o_fifo_ready;


    logic [ 7:0] pixel_data ;
    logic        pixel_valid, pixel_ready;
    logic        pixel_eof  ;
    logic [17:0] num_pixels ;

    logic clk  ;
    logic rst_n, rst;


    HSOSC #(.CLKHF_DIV("0b10")) u_hfosc (
        .CLKHFEN(1'b1),
        .CLKHFPU(1'b1),
        .CLKHF  (clk )
    );


    ice40_resetn u_reset_n (.clk(clk), .resetn(rst_n));
    assign rst = ~rst_n;


    logic [27:0] clk_divider;
    always @(posedge clk) begin
        if (rst)
            clk_divider <= 0;
        else
            clk_divider <= clk_divider + 1;
    end


    assign mic_clk = clk_divider[1];
    assign mic_ws  = clk_divider[1+$clog2(64)];


    logic        init, init_done;
    logic [19:0] timer;

    enum {
        S_POR,
        S_PROG,
        S_WAIT_INIT,
        S_WAIT_UART,
        S_WAIT_FRAME,
        S_WAIT_UART_TX,
        S_PAUSE_UART,
        S_XXX
    } s_state, s_next;

    always_ff @(posedge clk) begin
        if(rst) s_state <= S_POR;
        else s_state <= s_next;
    end

    always_comb begin
        s_next = S_XXX;
        case (s_state)
            S_POR          : if (&timer) s_next = S_PROG; else s_next = S_POR;
            S_PROG         : s_next = S_WAIT_INIT;
            S_WAIT_INIT    : if (init_done) s_next = S_WAIT_UART; else s_next = S_WAIT_INIT;
            S_WAIT_UART    : if (uart_rx_valid) s_next = S_WAIT_FRAME; else s_next = S_WAIT_UART;
            S_WAIT_FRAME   : if (pixel_eof) s_next = S_WAIT_UART_TX; else s_next = S_WAIT_FRAME;
            S_WAIT_UART_TX :
                begin
                    if (num_pixels == '0)
                        s_next = S_WAIT_UART;
                    else
                        if (~uart_tx_empty)
                            s_next = S_PAUSE_UART;
                    else
                        s_next = S_WAIT_UART_TX;
                end
            S_PAUSE_UART : if (uart_tx_empty) s_next = S_WAIT_UART_TX; else s_next = S_PAUSE_UART;
            S_XXX        : s_next = S_XXX;
        endcase
    end

    always_ff @(posedge clk) begin
        if(rst) begin
            timer <= '0;
            init  <= '0;
        end else begin
            init <= '0;

            case (s_state)
                S_POR        : timer <= timer + 'd1;
                S_PROG       : init <= '1;
                S_WAIT_INIT  : timer <= '0;
                S_WAIT_UART  : timer <= '0;
                S_WAIT_FRAME : ;
                S_WAIT_UART_TX, S_PAUSE_UART : ;
                S_XXX        : ;
            endcase
        end
    end







    always_ff @(posedge clk) begin
        if(rst) begin
            sensor_led <= 0;
        end else begin
            if (uart_rx_valid)
                sensor_led <= '1;
            else if (pixel_valid)
                sensor_led <= '0;
        end
    end





    logic w_scl_out, w_sda_out;
    lsc_i2cm_himax #(
        .NUM_CMD  (NUM_HIMAX_CMDS ),
        .INIT_FILE(HIMAX_INIT_FILE)
    ) u_lsc_i2cm_himax (
        .clk      (clk      ),
        .init     (init     ),
        .init_done(init_done),
        .scl_in   (i2c_scl  ),
        .sda_in   (i2c_sda  ),
        .scl_out  (w_scl_out),
        .sda_out  (w_sda_out),
        .resetn   (rst_n    )
    );

    assign i2c_scl = w_scl_out ? 1'bz : 1'b0;
    assign i2c_sda = w_sda_out ? 1'bz : 1'b0;



    assign sensor_clk = init_done ? 1'b0 : clk;







    logic [7:0] cam_data;
    logic [3:0] pxd_d   ;
    logic       hsync, vsync;
    logic [9:0] pxl_cnt ;
    logic       pxl_vld ;
    logic [3:0] pxd_n, pxd_p;


    IOL_B
        #(
            .LATCHIN ("NONE_DDR"),
            .DDROUT  ("NO")
        ) u_io_pxd[3:0] (
            .PADDI  (pxd[3:0]),
            .DO1    (1'b0),
            .DO0    (1'b0),
            .CE     (1'b1),
            .IOLTO  (1'b1),
            .HOLD   (1'b0),
            .INCLK  (px_clk),
            .OUTCLK (px_clk),
            .PADDO  (),
            .PADDT  (),
            .DI1    (pxd_n[3:0]),
            .DI0    (pxd_p[3:0])
        );

    logic px_fv_p;

    assign px_fv_p = px_fv;

    logic px_lv_p, px_lv_n;
    IOL_B #(
        .LATCHIN("NONE_DDR"),
        .DDROUT ("NO"      )
    ) u_io_lv (
        .PADDI (px_lv  ),
        .DO1   (1'b0   ),
        .DO0   (1'b0   ),
        .CE    (1'b1   ),
        .IOLTO (1'b1   ),
        .HOLD  (1'b0   ),
        .INCLK (px_clk ),
        .OUTCLK(px_clk ),
        .PADDO (       ),
        .PADDT (       ),
        .DI1   (px_lv_n),
        .DI0   (px_lv_p)
    );



    always_ff @(posedge px_clk) begin
        pxd_d    <= pxd_p;
        cam_data <= {pxd_d, pxd_p};
        hsync    <= px_lv_p;
        vsync    <= px_fv_p;
        if (px_lv_p == '0)
            pxl_cnt <= '0;
        else
            pxl_cnt <= pxl_cnt + 'd1;
    end

    assign pxl_vld = hsync && ~pxl_cnt[0];






    stream_dual_clock_fifo #(.DW(8), .AW(4)) i_stream_dual_clock_fifo (
        .wr_clk          (px_clk             ),
        .wr_rst          (rst                ),
        .stream_s_data_i (cam_data           ),
        .stream_s_valid_i(pxl_vld & load_fifo),
        .stream_s_ready_o(                   ),
        .rd_clk          (clk                ),
        .rd_rst          (rst                ),
        .stream_m_data_o (pixel_data         ),
        .stream_m_valid_o(pixel_valid        ),
        .stream_m_ready_i(pixel_ready        )
    );


    assign pixel_ready = '1;


    logic [1:0] vsync_d;
    logic       eof    ;
    always_ff @(posedge px_clk)
        vsync_d <= {vsync_d[0], vsync};

    assign eof = vsync_d[1] & ~vsync_d[0];


    logic [1:0] eof_d;
    always_ff @(posedge clk)
        eof_d <= {eof_d[0], eof};

    assign pixel_eof = ~eof_d[1] & eof_d[0];


    always_ff @(posedge clk) begin
        if(rst) begin
            load_fifo <= '0;
        end else begin
            if ((s_state == S_WAIT_UART) & uart_rx_valid)
                load_fifo <= '1;
            else if ((s_state == S_WAIT_FRAME) & eof)
                load_fifo <= '0;
        end
    end


    logic [16:0] ram_addr    ;
    logic        ram_cs, ram_wr_en;
    logic        ram_rd_valid;
    logic [ 7:0] ram_wr_data ;
    logic [ 7:0] ram_rd_data ;
    ice40_spram_128kx8 i_ice40_spram_128kx8 (
        .clk    (clk        ),
        .rst    (rst        ),
        .cs     (ram_cs     ),
        .addr   (ram_addr   ),
        .wr_en  (ram_wr_en  ),
        .wr_data(ram_wr_data),
        .rd_data(ram_rd_data)
    );


    assign ram_wr_en   = pixel_valid & (s_state == S_WAIT_FRAME);
    assign ram_cs      = (pixel_valid & (s_state == S_WAIT_FRAME) ) | (uart_tx_empty & (s_state == S_WAIT_UART_TX));
    assign ram_wr_data = pixel_data;

    always_ff @(posedge clk) begin
        if(rst) begin
            ram_addr   <= '0;
            num_pixels <= '0;
        end else begin


            ram_rd_valid <= ram_cs & ~ram_wr_en;





            case (s_state)
                S_POR, S_PROG, S_WAIT_INIT :;
                S_WAIT_UART  : ram_addr <= '0;
                S_WAIT_FRAME : begin
                    num_pixels <= num_pixels + pixel_valid;
                    if (eof)
                        ram_addr <= '0;
                    else
                        ram_addr <= ram_addr + pixel_valid;
                end
                S_WAIT_UART_TX : begin
                    num_pixels <= num_pixels - uart_tx_empty;
                    ram_addr   <= ram_addr + uart_tx_empty;
                end

                S_PAUSE_UART : ;
                S_XXX        : ;
            endcase
        end
    end

    assign uart_tx_valid = ram_rd_valid;
    assign uart_tx_data  = ram_rd_data;

    lsc_uart #(.PERIOD(UART_PERIOD)) u_lsc_uart (
        .ref_clk(clk          ),
        .clk    (clk          ),
        .resetn (~rst         ),
        
        .i_din  (uart_tx_data ),
        .i_valid(uart_tx_valid),
        .o_empty(uart_tx_empty),
        
        .o_dout (uart_rx_data ),
        .o_valid(uart_rx_valid),
        
        .i_rxd  (uart_rx      ),
        .o_txd  (uart_tx      )
    );







    logic duty_cycle;
    assign duty_cycle = '1;

    RGB u_led_driver (
        .CURREN  (1'b1     ),
        .RGBLEDEN(1'b1     ),
        .RGB0PWM (red      ),
        .RGB1PWM (green    ),
        .RGB2PWM (blue     ),
        .RGB0    (led_red  ),
        .RGB1    (led_green),
        .RGB2    (led_blue )
    );
    defparam u_led_driver.CURRENT_MODE = "1" ;
    defparam u_led_driver.RGB0_CURRENT = "0b000001";
    defparam u_led_driver.RGB1_CURRENT = "0b000001";
    defparam u_led_driver.RGB2_CURRENT = "0b000001";

    assign red   = ~clk_divider[22] && clk_divider[21] && duty_cycle;
    assign green = clk_divider[22] && ~clk_divider[21] && duty_cycle;
    assign blue  = clk_divider[22] && clk_divider[21] && duty_cycle;

    assign gpio[0]   = clk_divider[23];
    assign gpio[1]   = clk_divider[22];
    assign gpio[2]   = clk_divider[21];
    assign host_intr = clk_divider[20];

endmodule