data/full_repos/permissive/435890256/riscv_ref2/USTC-RVSoC/hardware/RTL/isp_uart.sv
1: b'%Warning-MULTITOP: data/full_repos/permissive/435890256/riscv_ref2/USTC-RVSoC/hardware/RTL/isp_uart.sv:12: Multiple top level modules\n                                                                                                         : ... Suggest see manual; fix the duplicates, or use --top-module to select top.\n                   ... Use "/* verilator lint_off MULTITOP */" and lint_on around source to disable this message.\n                                                                                                         : ... Top module \'isp_uart\'\nmodule isp_uart #(\n       ^~~~~~~~\n                                                                                                         : ... Top module \'naive_bus\'\n    naive_bus.master    bus,\n    ^~~~~~~~~\n%Error: data/full_repos/permissive/435890256/riscv_ref2/USTC-RVSoC/hardware/RTL/isp_uart.sv:12: Unsupported: Interfaced port on top level module\n    naive_bus.master    bus,\n                        ^~~\n%Error: data/full_repos/permissive/435890256/riscv_ref2/USTC-RVSoC/hardware/RTL/isp_uart.sv:13: Unsupported: Interfaced port on top level module\n    naive_bus.slave     user_uart_bus\n                        ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/435890256/riscv_ref2/USTC-RVSoC/hardware/RTL/isp_uart.sv:12: Cannot find file containing interface: \'naive_bus\'\n    naive_bus.master    bus,\n    ^~~~~~~~~\n%Error: data/full_repos/permissive/435890256/riscv_ref2/USTC-RVSoC/hardware/RTL/isp_uart.sv:13: Cannot find file containing interface: \'naive_bus\'\n    naive_bus.slave     user_uart_bus\n    ^~~~~~~~~\n%Error: Internal Error: data/full_repos/permissive/435890256/riscv_ref2/USTC-RVSoC/hardware/RTL/isp_uart.sv:12: ../V3LinkDot.cpp:2055: Unlinked interface\n    naive_bus.master    bus,\n    ^~~~~~~~~\n'
module isp_uart #(
    parameter  UART_RX_CLK_DIV = 108,
    parameter  UART_TX_CLK_DIV = 434
)(
    input  logic        clk,
    input  logic        i_uart_rx,
    output logic        o_uart_tx,
    output logic        o_rst_n,
    output logic [31:0] o_boot_addr,
    naive_bus.master    bus,
    naive_bus.slave     user_uart_bus
);

logic isp_uart_tx, user_uart_tx, isp_user_sel=1'b0;
logic uart_tx_line_fin;
logic [ 3:0] rst_chain = 4'b0;
logic rx_ready, rd_ok=1'b0, wr_ok=1'b0, tx_start=1'b0;
logic [ 7:0] rx_data, rx_data_raw, rx_binary;
logic [ 3:0] rx_binary_l;
logic [31:0] addr=0, wr_data=0;
logic [ 7:0][ 7:0] rd_data_ascii;
logic [ 7:0][ 7:0] tx_data = 64'h0;
enum  {NEW, CMD,OPEN,CLOSE,ADDR, EQUAL, DATA, FINAL, TRASH} fsm = NEW;
enum  {NONE, SELOPEN, SELCLOSE, RST} send_type = NONE;

`define  C  (rx_data=="r")
`define  OP (rx_data=="o")
`define  CL (rx_data=="s")
`define  S  (rx_data==" "  || rx_data=="\t" ) 
`define  E  (rx_data=="\n" || rx_data=="\r" ) 
`define  N  ( (rx_data>="0" && rx_data<="9" ) || (rx_data>="a" && rx_data<="f" ) )

initial o_boot_addr = 0;
assign  o_rst_n = &rst_chain;
assign  o_uart_tx = isp_user_sel ? isp_uart_tx : user_uart_tx;
initial begin bus.rd_req = 1'b0; bus.wr_req = 1'b0; bus.rd_addr = 0; bus.wr_addr = 0; bus.wr_data = 0; end
assign bus.rd_be = 4'hf;
assign bus.wr_be = 4'hf;

assign rx_binary_l = rx_binary[3:0];

uart_rx #(
    .UART_RX_CLK_DIV   (UART_RX_CLK_DIV)
) uart_rx_inst (
    .clk        ( clk           ),
    .i_rx       ( i_uart_rx     ),
    .o_ready    ( rx_ready      ),
    .o_data     ( rx_data_raw   )
);

uart_tx_line #(
    .UART_TX_CLK_DIV   (UART_TX_CLK_DIV)
) uart_tx_line_inst (
    .clk        ( clk              ),
    .o_tx       ( isp_uart_tx      ),
    .i_start    ( tx_start         ),
    .o_fin      ( uart_tx_line_fin ),
    .i_data     ( tx_data          )
);

user_uart_tx #(
    .UART_TX_CLK_DIV   (UART_TX_CLK_DIV)
) user_uart_in_isp_inst (
    .clk        ( clk           ),
    .rst_n      ( o_rst_n       ),
    .o_uart_tx  ( user_uart_tx  ),
    .bus        ( user_uart_bus )
);

always_comb
    if(rx_data_raw>="A" && rx_data_raw<="Z")
        rx_data <= rx_data_raw | 8'b00100000;
    else
        rx_data <= rx_data_raw;

always_comb
    if(rx_data>="0" && rx_data<="9" ) begin
        rx_binary = rx_data - "0";
    end else if(rx_data>="a" && rx_data<="f" ) begin
        rx_binary = rx_data - "a" + 8'd10;
    end else begin
        rx_binary = 8'h0;
    end

generate
    genvar i;
    for(i=0; i<8; i++) begin : convert_binary_to_ascii
        always_comb
            if(bus.rd_data[3+4*i:4*i]>4'h9)
                rd_data_ascii[i] = "a" - 8'd10 + bus.rd_data[3+4*i:4*i];
            else
                rd_data_ascii[i] = "0"         + bus.rd_data[3+4*i:4*i];
    end
endgenerate

always @ (posedge clk)
    rd_ok <= (bus.rd_req & bus.rd_gnt);
    
always @ (posedge clk)
    wr_ok <= (bus.wr_req & bus.wr_gnt);
    

always @ (posedge clk)
    if         (rd_ok) begin
        tx_start<= 1'b1;
        send_type <= NONE;
        tx_data <= rd_data_ascii;
    end else if(wr_ok) begin
        tx_start<= 1'b1;
        send_type <= NONE;
        tx_data <= "wr done ";
    end else if(rx_ready && `E) begin
        if(isp_user_sel==1'b0) begin
            tx_start<= 1'b1;
            send_type <= SELCLOSE;
            tx_data <= "\r\ndebug ";
        end else if(fsm==CMD) begin
            tx_start<= 1'b1;
            send_type <= RST;
            tx_data <= "rst done";
        end else if(fsm==OPEN) begin
            tx_start<= 1'b1;
            send_type <= SELOPEN;
            tx_data <= "user    ";
        end else if(fsm==TRASH) begin
            tx_start<= 1'b1;
            send_type <= NONE;
            tx_data <= "invalid ";
        end
    end else begin
        tx_start<= 1'b0;
        tx_data <= 64'h0;
    end
    
always @ (posedge clk)
    if(uart_tx_line_fin && send_type == RST)
        rst_chain <= 4'h0;
    else
        rst_chain <= {rst_chain[2:0],1'b1};
        
always @ (posedge clk)
    if(uart_tx_line_fin && (send_type == RST || send_type == SELOPEN) )
        isp_user_sel <= 1'b0;
    else if(rx_ready && `E )
        isp_user_sel <= 1'b1;

always @ (posedge clk)
    if         (bus.rd_req) begin
        if(bus.rd_gnt)
            bus.rd_req <= 1'b0;
    end else if(bus.wr_req) begin
        if(bus.wr_gnt)
            bus.wr_req <= 1'b0;
    end else if( rx_ready ) begin
        case(fsm)
        NEW       : if         (`C) begin
                        fsm <= CMD;
                        wr_data <= 0;
                    end else if(`OP) begin
                        fsm <= OPEN;
                    end else if(`S || `E) begin
                        fsm <= NEW;
                        addr <= 0;
                        wr_data <= 0;
                    end else if(`N) begin
                        fsm <= ADDR;
                        addr <= {addr[27:0], rx_binary_l};
                    end else        begin
                        fsm <= TRASH;
                    end
        OPEN      : if         (`E) begin
                        fsm <= NEW;
                    end else if(`S) begin
                        fsm <= OPEN;
                    end else        begin
                        fsm <= TRASH;
                    end
        CMD       : if         (`E) begin
                        o_boot_addr <= {wr_data[31:2],2'b00};
                        fsm <= NEW;
                        addr <= 0;
                        wr_data <= 0;
                    end else if(`S) begin
                        fsm <= CMD;
                    end else if(`N) begin
                        fsm <= CMD;
                        wr_data <= {wr_data[27:0], rx_binary_l};
                    end else        begin
                        fsm <= TRASH;
                    end
        ADDR      : if         (`E) begin
                        fsm <= NEW;
                        bus.rd_req <= 1'b1;
                        bus.rd_addr <= addr;
                        addr <= 0;
                        wr_data <= 0;
                    end else if(`N) begin
                        fsm <= ADDR;
                        addr <= {addr[27:0], rx_binary_l};
                    end else if(`S) begin
                        fsm <= EQUAL;
                    end else        begin
                        fsm <= TRASH;
                    end
        EQUAL     : if         (`E) begin
                        fsm <= NEW;
                        bus.rd_req <= 1'b1;
                        bus.rd_addr <= addr;
                        addr <= 0;
                        wr_data <= 0;
                    end else if(`N) begin
                        fsm <= DATA;
                        wr_data <= {wr_data[27:0], rx_binary_l};
                    end else if(`S) begin
                        fsm <= EQUAL;
                    end else        begin
                        fsm <= TRASH;
                    end
        DATA      : if         (`E) begin
                        fsm <= NEW;
                        bus.wr_req <= 1'b1;
                        bus.wr_addr <= addr;
                        bus.wr_data <= wr_data;
                        addr <= 0;
                        wr_data <= 0;
                    end else if(`N) begin
                        fsm <= DATA;
                        wr_data <= {wr_data[27:0], rx_binary_l};
                    end else if(`S) begin
                        fsm <= FINAL;
                    end else        begin
                        fsm <= TRASH;
                    end
        FINAL     : if         (`E) begin
                        fsm <= NEW;
                        bus.wr_req <= 1'b1;
                        bus.wr_addr <= addr;
                        bus.wr_data <= wr_data;
                        addr <= 0;
                        wr_data <= 0;
                    end else if(`S) begin
                        fsm <= FINAL;
                    end else        begin
                        fsm <= TRASH;
                    end
        default   : if         (`E) begin

                        fsm <= NEW;
                        addr <= 0;
                        wr_data <= 0;
                    end else        begin
                        fsm <= TRASH;
                    end
        endcase
    end

endmodule
module isp_uart #(
    parameter  UART_RX_CLK_DIV = 108,
    parameter  UART_TX_CLK_DIV = 434
)(
    input  logic        clk,
    input  logic        i_uart_rx,
    output logic        o_uart_tx,
    output logic        o_rst_n,
    output logic [31:0] o_boot_addr,
    naive_bus.master    bus,
    naive_bus.slave     user_uart_bus
);


logic isp_uart_tx, user_uart_tx, isp_user_sel=1'b0;
logic uart_tx_line_fin;
logic [ 3:0] rst_chain = 4'b0;
logic rx_ready, rd_ok=1'b0, wr_ok=1'b0, tx_start=1'b0;
logic [ 7:0] rx_data, rx_data_raw, rx_binary;
logic [ 3:0] rx_binary_l;
logic [31:0] addr=0, wr_data=0;
logic [ 7:0][ 7:0] rd_data_ascii;
logic [ 7:0][ 7:0] tx_data = 64'h0;
enum  {NEW, CMD,OPEN,CLOSE,ADDR, EQUAL, DATA, FINAL, TRASH} fsm = NEW;
enum  {NONE, SELOPEN, SELCLOSE, RST} send_type = NONE;

`define  C  (rx_data=="r")
`define  OP (rx_data=="o")
`define  CL (rx_data=="s")
`define  S  (rx_data==" "  || rx_data=="\t" ) 
`define  E  (rx_data=="\n" || rx_data=="\r" ) 
`define  N  ( (rx_data>="0" && rx_data<="9" ) || (rx_data>="a" && rx_data<="f" ) )

initial o_boot_addr = 0;
assign  o_rst_n = &rst_chain;
assign  o_uart_tx = isp_user_sel ? isp_uart_tx : user_uart_tx;
initial begin bus.rd_req = 1'b0; bus.wr_req = 1'b0; bus.rd_addr = 0; bus.wr_addr = 0; bus.wr_data = 0; end
assign bus.rd_be = 4'hf;
assign bus.wr_be = 4'hf;

assign rx_binary_l = rx_binary[3:0];

uart_rx #(
    .UART_RX_CLK_DIV   (UART_RX_CLK_DIV)
) uart_rx_inst (
    .clk        ( clk           ),
    .i_rx       ( i_uart_rx     ),
    .o_ready    ( rx_ready      ),
    .o_data     ( rx_data_raw   )
);

uart_tx_line #(
    .UART_TX_CLK_DIV   (UART_TX_CLK_DIV)
) uart_tx_line_inst (
    .clk        ( clk              ),
    .o_tx       ( isp_uart_tx      ),
    .i_start    ( tx_start         ),
    .o_fin      ( uart_tx_line_fin ),
    .i_data     ( tx_data          )
);

user_uart_tx #(
    .UART_TX_CLK_DIV   (UART_TX_CLK_DIV)
) user_uart_in_isp_inst (
    .clk        ( clk           ),
    .rst_n      ( o_rst_n       ),
    .o_uart_tx  ( user_uart_tx  ),
    .bus        ( user_uart_bus )
);

always_comb
    if(rx_data_raw>="A" && rx_data_raw<="Z")
        rx_data <= rx_data_raw | 8'b00100000;
    else
        rx_data <= rx_data_raw;

always_comb
    if(rx_data>="0" && rx_data<="9" ) begin
        rx_binary = rx_data - "0";
    end else if(rx_data>="a" && rx_data<="f" ) begin
        rx_binary = rx_data - "a" + 8'd10;
    end else begin
        rx_binary = 8'h0;
    end

generate
    genvar i;
    for(i=0; i<8; i++) begin : convert_binary_to_ascii
        always_comb
            if(bus.rd_data[3+4*i:4*i]>4'h9)
                rd_data_ascii[i] = "a" - 8'd10 + bus.rd_data[3+4*i:4*i];
            else
                rd_data_ascii[i] = "0"         + bus.rd_data[3+4*i:4*i];
    end
endgenerate

always @ (posedge clk)
    rd_ok <= (bus.rd_req & bus.rd_gnt);
    
always @ (posedge clk)
    wr_ok <= (bus.wr_req & bus.wr_gnt);
    

always @ (posedge clk)
    if         (rd_ok) begin
        tx_start<= 1'b1;
        send_type <= NONE;
        tx_data <= rd_data_ascii;
    end else if(wr_ok) begin
        tx_start<= 1'b1;
        send_type <= NONE;
        tx_data <= "wr done ";
    end else if(rx_ready && `E) begin
        if(isp_user_sel==1'b0) begin
            tx_start<= 1'b1;
            send_type <= SELCLOSE;
            tx_data <= "\r\ndebug ";
        end else if(fsm==CMD) begin
            tx_start<= 1'b1;
            send_type <= RST;
            tx_data <= "rst done";
        end else if(fsm==OPEN) begin
            tx_start<= 1'b1;
            send_type <= SELOPEN;
            tx_data <= "user    ";
        end else if(fsm==TRASH) begin
            tx_start<= 1'b1;
            send_type <= NONE;
            tx_data <= "invalid ";
        end
    end else begin
        tx_start<= 1'b0;
        tx_data <= 64'h0;
    end
    
always @ (posedge clk)
    if(uart_tx_line_fin && send_type == RST)
        rst_chain <= 4'h0;
    else
        rst_chain <= {rst_chain[2:0],1'b1};
        
always @ (posedge clk)
    if(uart_tx_line_fin && (send_type == RST || send_type == SELOPEN) )
        isp_user_sel <= 1'b0;
    else if(rx_ready && `E )
        isp_user_sel <= 1'b1;

always @ (posedge clk)
    if         (bus.rd_req) begin
        if(bus.rd_gnt)
            bus.rd_req <= 1'b0;
    end else if(bus.wr_req) begin
        if(bus.wr_gnt)
            bus.wr_req <= 1'b0;
    end else if( rx_ready ) begin
        case(fsm)
        NEW       : if         (`C) begin
                        fsm <= CMD;
                        wr_data <= 0;
                    end else if(`OP) begin
                        fsm <= OPEN;
                    end else if(`S || `E) begin
                        fsm <= NEW;
                        addr <= 0;
                        wr_data <= 0;
                    end else if(`N) begin
                        fsm <= ADDR;
                        addr <= {addr[27:0], rx_binary_l};
                    end else        begin
                        fsm <= TRASH;
                    end
        OPEN      : if         (`E) begin
                        fsm <= NEW;
                    end else if(`S) begin
                        fsm <= OPEN;
                    end else        begin
                        fsm <= TRASH;
                    end
        CMD       : if         (`E) begin
                        o_boot_addr <= {wr_data[31:2],2'b00};
                        fsm <= NEW;
                        addr <= 0;
                        wr_data <= 0;
                    end else if(`S) begin
                        fsm <= CMD;
                    end else if(`N) begin
                        fsm <= CMD;
                        wr_data <= {wr_data[27:0], rx_binary_l};
                    end else        begin
                        fsm <= TRASH;
                    end
        ADDR      : if         (`E) begin
                        fsm <= NEW;
                        bus.rd_req <= 1'b1;
                        bus.rd_addr <= addr;
                        addr <= 0;
                        wr_data <= 0;
                    end else if(`N) begin
                        fsm <= ADDR;
                        addr <= {addr[27:0], rx_binary_l};
                    end else if(`S) begin
                        fsm <= EQUAL;
                    end else        begin
                        fsm <= TRASH;
                    end
        EQUAL     : if         (`E) begin
                        fsm <= NEW;
                        bus.rd_req <= 1'b1;
                        bus.rd_addr <= addr;
                        addr <= 0;
                        wr_data <= 0;
                    end else if(`N) begin
                        fsm <= DATA;
                        wr_data <= {wr_data[27:0], rx_binary_l};
                    end else if(`S) begin
                        fsm <= EQUAL;
                    end else        begin
                        fsm <= TRASH;
                    end
        DATA      : if         (`E) begin
                        fsm <= NEW;
                        bus.wr_req <= 1'b1;
                        bus.wr_addr <= addr;
                        bus.wr_data <= wr_data;
                        addr <= 0;
                        wr_data <= 0;
                    end else if(`N) begin
                        fsm <= DATA;
                        wr_data <= {wr_data[27:0], rx_binary_l};
                    end else if(`S) begin
                        fsm <= FINAL;
                    end else        begin
                        fsm <= TRASH;
                    end
        FINAL     : if         (`E) begin
                        fsm <= NEW;
                        bus.wr_req <= 1'b1;
                        bus.wr_addr <= addr;
                        bus.wr_data <= wr_data;
                        addr <= 0;
                        wr_data <= 0;
                    end else if(`S) begin
                        fsm <= FINAL;
                    end else        begin
                        fsm <= TRASH;
                    end
        default   : if         (`E) begin

                        fsm <= NEW;
                        addr <= 0;
                        wr_data <= 0;
                    end else        begin
                        fsm <= TRASH;
                    end
        endcase
    end

endmodule