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

📄 pci_spoci_ctrl.v

📁 这是用pci-wishbone核和16450串口核在xilinx的fpga上实现的串口程序
💻 V
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////////                                                              ////////  File name: pci_spoci_ctrl                                   ////////                                                              ////////  This file is part of the "PCI bridge" project               ////////  http://www.opencores.org/cores/pci/                         ////////                                                              ////////  Author(s):                                                  ////////      - Miha Dolenc (mihad@opencores.org)                     ////////                                                              ////////                                                              //////////////////////////////////////////////////////////////////////////////                                                              //////// Copyright (C) 2004 Miha Dolenc, mihad@opencores.org          ////////                                                              //////// This source file may be used and distributed without         //////// restriction provided that this copyright statement is not    //////// removed from the file and that any derivative work contains  //////// the original copyright notice and the associated disclaimer. ////////                                                              //////// This source file is free; you can redistribute it            //////// and/or modify it under the terms of the GNU Lesser General   //////// Public License as published by the Free Software Foundation; //////// either version 2.1 of the License, or (at your option) any   //////// later version.                                               ////////                                                              //////// This source is distributed in the hope that it will be       //////// useful, but WITHOUT ANY WARRANTY; without even the implied   //////// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //////// PURPOSE.  See the GNU Lesser General Public License for more //////// details.                                                     ////////                                                              //////// You should have received a copy of the GNU Lesser General    //////// Public License along with this source; if not, download it   //////// from http://www.opencores.org/lgpl.shtml                     ////////                                                              ////////////////////////////////////////////////////////////////////////////// CVS Revision History//// $Log: pci_spoci_ctrl.v,v $// Revision 1.1  2004/01/24 11:54:18  mihad// Update! SPOCI Implemented!////`include "pci_constants.v"// synopsys translate_off`include "timescale.v"// synopsys translate_onmodule pci_spoci_ctrl(    reset_i             ,    clk_i               ,                            do_rnd_read_i       ,    do_seq_read_i       ,    do_write_i          ,                            write_done_o        ,    dat_rdy_o           ,    no_ack_o            ,                            adr_i               ,    dat_i               ,    dat_o               ,    pci_spoci_sda_i     ,    pci_spoci_sda_oe_o  ,    pci_spoci_scl_oe_o);parameter tx_rx_state_width = 9     ;parameter tx_rx_idle        = 'h1   ;parameter tx_rx_start       = 'h2   ;parameter tx_rx_restart     = 'h4   ;parameter tx_rx_send_bits   = 'h8   ;parameter tx_rx_rec_bits    = 'h10  ;parameter tx_rx_send_ack    = 'h20  ;parameter tx_rx_rec_ack     = 'h40  ;parameter tx_rx_send_nack   = 'h80  ;parameter tx_rx_stop        = 'h100 ;parameter rw_seq_state_width    = 5     ;parameter rw_seq_idle           = 'h1   ;parameter rw_seq_tx_ctrl        = 'h2   ;parameter rw_seq_tx_adr         = 'h4   ;parameter rw_seq_tx_byte        = 'h8   ;parameter rw_seq_rx_byte        = 'h10  ;`ifdef PCI33parameter cnt_width     = 9     ;parameter period_cnt    = 334   ;`endif`ifdef PCI66parameter cnt_width     = 10    ;parameter period_cnt    = 667   ;`endifinput   reset_i ,        clk_i   ;input   do_rnd_read_i   ,        do_seq_read_i   ,        do_write_i      ;output  write_done_o    ,        dat_rdy_o       ,        no_ack_o        ;input   [10: 0] adr_i   ;input   [ 7: 0] dat_i   ;output  [ 7: 0] dat_o   ;input   pci_spoci_sda_i     ;output  pci_spoci_sda_oe_o  ,        pci_spoci_scl_oe_o  ;reg write_done_o    ,    dat_rdy_o       ,    no_ack_o        ;reg [ 7: 0] dat_o   ;reg pci_spoci_sda_oe_o  ,    pci_spoci_scl_oe_o  ;reg clk_gen_cnt_en  ;reg clk_gen_cnt_clr ;reg [cnt_width - 1:0] clk_gen_cnt   ;reg [tx_rx_state_width - 1:0] tx_rx_state       ;reg [tx_rx_state_width - 1:0] tx_rx_next_state  ;reg tx_rx_sm_idle ;reg scl_oe      ;reg scl_oe_en   ;reg sda_oe      ;reg sda_oe_en   ;reg sda_i_reg_en    ;reg sda_i_reg       ;always@(posedge clk_i or posedge reset_i)begin    if (reset_i)    begin        clk_gen_cnt <= 'h0  ;        tx_rx_state <= tx_rx_idle   ;    `ifdef ACTIVE_LOW_OE        pci_spoci_sda_oe_o <= 1'b1 ;        pci_spoci_scl_oe_o <= 1'b1 ;    `endif    `ifdef ACTIVE_HIGH_OE        pci_spoci_sda_oe_o <= 1'b0 ;        pci_spoci_scl_oe_o <= 1'b0 ;    `endif        sda_i_reg <= 1'b1 ;    end    else    begin        tx_rx_state <= tx_rx_next_state ;                if (clk_gen_cnt_clr)            clk_gen_cnt <= 'h0  ;        else if (clk_gen_cnt_en)            clk_gen_cnt <= clk_gen_cnt + 1'b1 ;            if (sda_oe_en)        begin        `ifdef ACTIVE_LOW_OE            pci_spoci_sda_oe_o <= ~sda_oe   ;        `endif        `ifdef ACTIVE_HIGH_OE            pci_spoci_sda_oe_o <= sda_oe    ;        `endif        end        if (scl_oe_en)        begin        `ifdef ACTIVE_LOW_OE            pci_spoci_scl_oe_o <= ~scl_oe   ;        `endif        `ifdef ACTIVE_HIGH_OE            pci_spoci_scl_oe_o <= scl_oe    ;        `endif        end        if (sda_i_reg_en)            sda_i_reg <= pci_spoci_sda_i ;    endendreg [ 7: 0] tx_shift_reg ;reg send_start  ;reg start_sent  ;reg send_bit    ;reg bit_sent    ;reg rec_bit     ;reg bit_rec     ;reg rec_ack     ;reg ack_rec     ;reg nack_rec    ;reg send_ack    ;reg ack_sent    ;reg send_nack   ;reg nack_sent   ;reg send_stop   ;reg stop_sent   ;always@(    tx_rx_state     or    clk_gen_cnt     or    send_start      or    send_bit        or    tx_shift_reg    or    send_stop       or    rec_ack         or    sda_i_reg       or    rec_bit         or    send_ack        or    send_nack)begin    clk_gen_cnt_clr     = 1'b0          ;    clk_gen_cnt_en      = 1'b0          ;    tx_rx_next_state    = tx_rx_state   ;    tx_rx_sm_idle       = 1'b0          ;    scl_oe              = 1'b0          ;    sda_oe              = 1'b0          ;    scl_oe_en           = 1'b0          ;    sda_oe_en           = 1'b0          ;    start_sent          = 1'b0          ;    bit_sent            = 1'b0          ;    ack_rec             = 1'b0          ;    nack_rec            = 1'b0          ;    sda_i_reg_en        = 1'b0          ;    stop_sent           = 1'b0          ;    bit_rec             = 1'b0          ;    ack_sent            = 1'b0          ;    nack_sent           = 1'b0          ;    case (tx_rx_state)    tx_rx_idle:    begin        tx_rx_sm_idle = 1'b1 ;        // from idle state, the only transition can be to the send start bit        if (send_start)        begin            tx_rx_next_state = tx_rx_start  ;            clk_gen_cnt_clr  = 1'b1         ;        end    end    tx_rx_start:    begin        clk_gen_cnt_en  = 1'b1  ;        sda_oe          = 1'b1  ;        // start bit is sent by transmiting 0 on the sda line        if (clk_gen_cnt == (period_cnt >> 1))        begin            start_sent = 1'b1 ;            sda_oe_en  = 1'b1 ;        end                // after half clock period of driving the sda low, the only possible        // transition is to send state.        // if send bit is not active, stop the procedure - undrive sda        if (clk_gen_cnt == period_cnt)        begin            clk_gen_cnt_clr = 1'b1 ;            if (send_bit)            begin                tx_rx_next_state = tx_rx_send_bits ;            end            else            begin                sda_oe              = 1'b0          ;                sda_oe_en           = 1'b1          ;                tx_rx_next_state    = tx_rx_idle    ;            end        end    end    tx_rx_send_bits:    begin        clk_gen_cnt_en = 1'b1 ;        // generate high to low transition on the scl line immediately        if (clk_gen_cnt == 'h0)        begin            scl_oe      = 1'b1  ;            scl_oe_en   = 1'b1  ;        end        // after half of clock low time, load new value for sda oe, depending on the        // msb bit in the shift register        if (clk_gen_cnt == (period_cnt >> 2))        begin            sda_oe      = ~tx_shift_reg[7]  ;            sda_oe_en   = 1'b1              ;            bit_sent    = 1'b1              ;        end        // after clock low time, 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 high time, check what to do next        if (clk_gen_cnt == (period_cnt))        begin            clk_gen_cnt_clr = 1'b1 ;            if (~send_bit)            begin                // after transmiting all the bits, the only possible transition is to the state                // that checks the eprom acknowledge                if (rec_ack)                    tx_rx_next_state = tx_rx_rec_ack ;                else                begin                    sda_oe              = 1'b0          ;                    sda_oe_en           = 1'b1          ;                    tx_rx_next_state    = tx_rx_idle    ;                end            end        end    end    tx_rx_rec_bits:    begin        clk_gen_cnt_en = 1'b1 ;        sda_i_reg_en   = 1'b1 ;        // generate high to low transition on the scl line immediately        if (clk_gen_cnt == 'h0)        begin            scl_oe      = 1'b1  ;            scl_oe_en   = 1'b1  ;        end        // after half of clock low time, disable sda driver        if (clk_gen_cnt == (period_cnt >> 2))        begin            sda_oe      = 1'b0  ;            sda_oe_en   = 1'b1  ;        end        // after clock low time, 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 half of clock high time, report received bit        if (clk_gen_cnt == ((period_cnt >> 1) + (period_cnt >> 2)) )        begin            bit_rec = 1'b1  ;        end        // after clock period is finished, check the next operation        if (clk_gen_cnt == (period_cnt))        begin            clk_gen_cnt_clr = 1'b1 ;            if (~rec_bit)            begin                // when all bits are received, only nack or ack next states are possible                if (send_ack)                    tx_rx_next_state = tx_rx_send_ack   ;                else if (send_nack)                    tx_rx_next_state = tx_rx_send_nack  ;                else                begin                    tx_rx_next_state = tx_rx_idle    ;                end            end        end    end    tx_rx_send_ack:    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, enable the sda driver        if (clk_gen_cnt == (period_cnt >> 2))        begin            sda_oe      = 1'b1  ;            sda_oe_en   = 1'b1  ;            ack_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 byte is acknowledged, the only possible next state is receive bits            // state            if (rec_bit)                tx_rx_next_state = tx_rx_rec_bits   ;            else            begin                // this should never happen                sda_oe      = 1'b0  ;                sda_oe_en   = 1'b1  ;                tx_rx_next_state = tx_rx_idle ;            end        end    end    tx_rx_rec_ack:    begin        clk_gen_cnt_en  = 1'b1  ;        sda_i_reg_en    = 1'b1  ;        // generate high to low transition on the scl line

⌨️ 快捷键说明

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