⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pci_spoci_ctrl.v

📁 这是用pci-wishbone核和16450串口核在xilinx的fpga上实现的串口程序
💻 V
📖 第 1 页 / 共 2 页
字号:
        if (clk_gen_cnt == 'h0)        begin            scl_oe      = 1'b1  ;            scl_oe_en   = 1'b1  ;        end        // after half of clock low time, disable the sda driver        if (clk_gen_cnt == (period_cnt >> 2))        begin            sda_oe      = 1'b0  ;            sda_oe_en   = 1'b1  ;        end        // after clock low time, disable the scl driver - generate low to high transition on the scl line        if (clk_gen_cnt == (period_cnt >> 1))        begin            scl_oe      = 1'b0  ;            scl_oe_en   = 1'b1  ;        end        // after 1/2 clock high time, report ack or nack condition, depending on the sda input state        if (clk_gen_cnt == ((period_cnt >> 1) + (period_cnt >> 2)) )        begin            ack_rec     = ~sda_i_reg ;            nack_rec    =  sda_i_reg ;        end        // after clock period time expires, check what to do next        if (clk_gen_cnt == period_cnt)        begin            clk_gen_cnt_clr = 1'b1 ;            if (send_bit)                tx_rx_next_state = tx_rx_send_bits  ;            else if (rec_bit)                tx_rx_next_state = tx_rx_rec_bits   ;            else if (send_stop)                tx_rx_next_state = tx_rx_stop       ;            else if (send_start)                tx_rx_next_state = tx_rx_restart    ;            else            begin                // this should never happen                tx_rx_next_state = tx_rx_idle ;            end        end    end    tx_rx_send_nack:    begin        clk_gen_cnt_en  = 1'b1  ;        // generate high to low transition on the scl line        if (clk_gen_cnt == 'h0)        begin            scl_oe      = 1'b1  ;            scl_oe_en   = 1'b1  ;        end        // after half of clock low time, disable the sda driver        if (clk_gen_cnt == (period_cnt >> 2))        begin            sda_oe      = 1'b0  ;            sda_oe_en   = 1'b1  ;            nack_sent   = 1'b1  ;        end        // after clock low time, disable the scl driver - generate low to high transition on the scl line        if (clk_gen_cnt == (period_cnt >> 1))        begin            scl_oe      = 1'b0  ;            scl_oe_en   = 1'b1  ;        end        // after clock period time expires, check what to do next        if (clk_gen_cnt == period_cnt)        begin            clk_gen_cnt_clr = 1'b1 ;            // after the no acknowledge is sent, the only possible next state is stop            // state            if (send_stop)                tx_rx_next_state = tx_rx_stop   ;            else            begin                // this should never happen                tx_rx_next_state = tx_rx_idle ;            end        end    end    tx_rx_restart:    begin        clk_gen_cnt_en = 1'b1 ;        // generate high to low transition        if (clk_gen_cnt == 'h0)        begin            scl_oe      = 1'b1  ;            scl_oe_en   = 1'b1  ;        end        // after half of clock low time, release sda line        if (clk_gen_cnt == (period_cnt >> 2))        begin            sda_oe      = 1'b0  ;            sda_oe_en   = 1'b1  ;        end        // generate low to high transition        if (clk_gen_cnt == (period_cnt >> 1))        begin            clk_gen_cnt_clr = 1'b1 ;            scl_oe      = 1'b0  ;            scl_oe_en   = 1'b1  ;            if (send_start)                tx_rx_next_state = tx_rx_start ;            else                tx_rx_next_state = tx_rx_idle ;        end    end    tx_rx_stop:    begin        clk_gen_cnt_en = 1'b1 ;        // generate high to low transition        if (clk_gen_cnt == 'h0)        begin            scl_oe      = 1'b1  ;            scl_oe_en   = 1'b1  ;        end        // after half of clock low time, drive sda line low        if (clk_gen_cnt == (period_cnt >> 2))        begin            sda_oe      = 1'b1  ;            sda_oe_en   = 1'b1  ;        end        // generate low to high transition        if (clk_gen_cnt == (period_cnt >> 1))        begin            scl_oe      = 1'b0  ;            scl_oe_en   = 1'b1  ;        end        // after full clock period, release the sda line        if (clk_gen_cnt == period_cnt)        begin            sda_oe      = 1'b0  ;            sda_oe_en   = 1'b1  ;            stop_sent   = 1'b1  ;            tx_rx_next_state = tx_rx_idle ;        end    end    endcaseendreg [rw_seq_state_width - 1:0]  rw_seq_state    ;reg doing_read      ,     doing_write     ,     doing_seq_read  ,    adr_set         ;reg [ 3: 0] bits_transfered ;always@(posedge clk_i or posedge reset_i)begin    if (reset_i)    begin        rw_seq_state    <= rw_seq_idle  ;        adr_set         <= 1'b0         ;        doing_read      <= 1'b0         ;        doing_write     <= 1'b0         ;        doing_seq_read  <= 1'b0         ;        dat_o           <= 'h0          ;        tx_shift_reg    <= 'h0          ;        send_start      <= 'h0          ;        send_stop       <= 'h0          ;        send_bit        <= 'h0          ;        send_nack       <= 'h0          ;        rec_ack         <= 'h0          ;        no_ack_o        <= 'h0          ;        bits_transfered <= 'h0          ;        write_done_o    <= 'h0          ;        dat_rdy_o       <= 'h0          ;        send_ack        <= 'h0          ;        rec_bit         <= 'h0          ;    end    else    begin        case (rw_seq_state)                    rw_seq_idle:        begin            tx_shift_reg <= {4'b1010, adr_i[10: 8], 1'b0} ;            adr_set      <= 1'b0                          ;            if ( tx_rx_sm_idle & ~(doing_write | doing_read | doing_seq_read) )            begin                if (do_write_i | do_rnd_read_i | do_seq_read_i)                begin                    rw_seq_state <= rw_seq_tx_ctrl  ;                    send_start   <= 1'b1            ;                end                if (do_write_i)                    doing_write     <= 1'b1 ;                else if (do_rnd_read_i)                    doing_read      <= 1'b1 ;                else if (do_seq_read_i)                    doing_seq_read  <= 1'b1 ;            end            else            begin                doing_write     <= 1'b0 ;                doing_read      <= 1'b0 ;                doing_seq_read  <= 1'b0 ;            end        end            rw_seq_tx_ctrl:        begin            if (send_start)            begin                bits_transfered <= 'h0 ;                if (start_sent)                begin                    send_start <= 1'b0 ;                    send_bit   <= 1'b1 ;                end            end            else if (send_bit)            begin                if (bit_sent)                begin                    bits_transfered <= bits_transfered + 1'b1 ;                    tx_shift_reg <= {tx_shift_reg[6:0], tx_shift_reg[0]} ;                end                if (bits_transfered == 'h8)                begin                    send_bit <= 1'b0 ;                    rec_ack  <= 1'b1 ;                end            end            else if (rec_ack)            begin                bits_transfered <= 'h0 ;                if (ack_rec | nack_rec)                    rec_ack <= 1'b0 ;                if (ack_rec)                begin                    if (doing_write | ~adr_set)                    begin                        rw_seq_state    <= rw_seq_tx_adr    ;                        tx_shift_reg    <= adr_i[ 7: 0]     ;                        send_bit        <= 1'b1             ;                    end                    else                    begin                        rw_seq_state    <= rw_seq_rx_byte   ;                        rec_bit         <= 1'b1             ;                    end                end                else if (nack_rec)                begin                    no_ack_o    <= 1'b1 ;                    send_stop   <= 1'b1 ;                end            end            else if (send_stop)            begin                no_ack_o <= 1'b0 ;                if (stop_sent)                begin                    send_stop       <= 1'b0         ;                    rw_seq_state    <= rw_seq_idle  ;                end            end        end            rw_seq_tx_adr:        begin            if (send_bit)            begin                if (bit_sent)                begin                    bits_transfered <= bits_transfered + 1'b1 ;                    tx_shift_reg <= {tx_shift_reg[6:0], tx_shift_reg[0]} ;                end                if (bits_transfered == 'h8)                begin                    send_bit <= 1'b0 ;                    rec_ack  <= 1'b1 ;                end            end            else if (rec_ack)            begin                bits_transfered <= 'h0 ;                if (ack_rec | nack_rec)                    rec_ack <= 1'b0 ;                if (ack_rec)                begin                    adr_set <= 1'b1 ;                    if (doing_write)                    begin                        send_bit        <= 1'b1             ;                        rw_seq_state    <= rw_seq_tx_byte   ;                        tx_shift_reg    <= dat_i            ;                    end                    else if (doing_read | doing_seq_read)                    begin                        send_start      <= 1'b1             ;                        rw_seq_state    <= rw_seq_tx_ctrl   ;                        tx_shift_reg    <= 8'b10100001      ;                    end                end                else if (nack_rec)                begin                    no_ack_o    <= 1'b1 ;                    send_stop   <= 1'b1 ;                end            end            else if (send_stop)            begin                no_ack_o    <= 1'b0 ;                if (stop_sent)                begin                    send_stop       <= 1'b0         ;                    rw_seq_state    <= rw_seq_idle  ;                end            end        end            rw_seq_tx_byte:        begin            if (send_bit)            begin                if (bit_sent)                begin                    bits_transfered <= bits_transfered + 1'b1 ;                    tx_shift_reg <= {tx_shift_reg[6:0], tx_shift_reg[0]} ;                end                if (bits_transfered == 'h8)                begin                    send_bit <= 1'b0 ;                    rec_ack  <= 1'b1 ;                end            end            else if (rec_ack)            begin                bits_transfered <= 'h0 ;                if (ack_rec | nack_rec)                begin                    rec_ack   <= 1'b0   ;                    send_stop <= 1'b1   ;                end                if (nack_rec)                    no_ack_o <= 1'b1 ;                if (ack_rec)                    write_done_o <= 1'b1 ;            end            else if (send_stop)            begin                no_ack_o        <= 1'b0 ;                write_done_o    <= 1'b0 ;                if (stop_sent)                begin                    send_stop       <= 1'b0         ;                    rw_seq_state    <= rw_seq_idle  ;                end            end        end            rw_seq_rx_byte:        begin            if (rec_bit)            begin                if (bit_rec)                begin                    bits_transfered <= bits_transfered + 1'b1   ;                    dat_o           <= {dat_o[6:0], sda_i_reg}  ;                end                if (bits_transfered == 'h8)                begin                    rec_bit   <= 1'b0 ;                    dat_rdy_o <= 1'b1 ;                    if (doing_read)                        send_nack <= 1'b1 ;                    else                        send_ack  <= 1'b1 ;                end            end            else if (send_nack)            begin                dat_rdy_o       <= 1'b0 ;                bits_transfered <= 'h0  ;                if (nack_sent)                begin                    send_stop <= 1'b1 ;                    send_nack <= 1'b0 ;                end            end            else if (send_ack)            begin                dat_rdy_o       <= 1'b0 ;                bits_transfered <= 'h0  ;                if (~do_seq_read_i)                begin                    send_ack    <= 1'b0 ;                    send_nack   <= 1'b1 ;                end                else if (ack_sent)                begin                    send_ack <= 1'b0 ;                    rec_bit  <= 1'b1 ;                end            end            else if (send_stop)            begin                if (stop_sent)                  begin                    send_stop       <= 1'b0         ;                    rw_seq_state    <= rw_seq_idle  ;                end            end        end        endcase    endendendmodule // pci_spoci_ctrl

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -