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

📄 wb_lpc_periph.v

📁 Wishbone to LPC (Low-Pin Count) Bridge, includes master and slave modules. Supports 8-bit I/O Read a
💻 V
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////////                                                              ////////  $Id: wb_lpc_periph.v,v 1.4 2008-07-26 19:15:32 hharte Exp $ ////////  wb_lpc_periph.v - LPC Peripheral to Wishbone Master Bridge  ////////                                                              ////////  This file is part of the Wishbone LPC Bridge project        ////////  http://www.opencores.org/projects/wb_lpc/                   ////////                                                              ////////  Author:                                                     ////////      - Howard M. Harte (hharte@opencores.org)                ////////                                                              //////////////////////////////////////////////////////////////////////////////                                                              //////// Copyright (C) 2008 Howard M. Harte                           ////////                                                              //////// 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 software; 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                     ////////                                                              //////////////////////////////////////////////////////////////////////////`timescale 1 ns / 1 ns`include "../../rtl/verilog/wb_lpc_defines.v"//              I/O Write       I/O Read        DMA Read        DMA Write//                                                          //  States - 1. H Start         H Start         H Start         H Start//           2. H CYCTYPE+DIR   H CYCTYPE+DIR   H CYCTYPE+DIR   H CYCTYPE+DIR//           3. H Addr (4)      H Addr (4)      H CHAN+TC       H CHAN+TC//                                              H SIZE          H SIZE//           4. H Data (2)      H TAR  (2)    +-H DATA (2)      H TAR  (2)//           5. H TAR  (2)      P SYNC (1+)   | H TAR  (2)    +-P SYNC (1+)//           6. P SYNC (1+)     P DATA (2)    | H SYNC (1+)   +-P DATA (2)//           7. P TAR  (2)      P TAR  (2)    +-P TAR  (2)      P TAR//                                                          module wb_lpc_periph(clk_i, nrst_i, wbm_adr_o, wbm_dat_o, wbm_dat_i, wbm_sel_o, wbm_tga_o, wbm_we_o,                     wbm_stb_o, wbm_cyc_o, wbm_ack_i, wbm_err_i,                     dma_chan_o, dma_tc_o,                     lframe_i, lad_i, lad_o, lad_oe);    // Wishbone Master Interface    input              clk_i;    input              nrst_i;    output reg  [31:0] wbm_adr_o;    output reg  [31:0] wbm_dat_o;    input       [31:0] wbm_dat_i;    output reg   [3:0] wbm_sel_o;    output reg   [1:0] wbm_tga_o;    output reg         wbm_we_o;    output reg         wbm_stb_o;    output reg         wbm_cyc_o;    input              wbm_ack_i;    input              wbm_err_i;	     // LPC Slave Interface    input              lframe_i;    // LPC Frame input (active high)    output reg         lad_oe;      // LPC AD Output Enable    input        [3:0] lad_i;       // LPC AD Input Bus    output reg   [3:0] lad_o;       // LPC AD Output Bus    // DMA-Specific sideband signals    output       [2:0] dma_chan_o;  // DMA Channel    output             dma_tc_o;    // DMA Terminal Count    reg         [13:0] state;       // Current state    reg          [2:0] adr_cnt;     // Address nibble counter    reg          [3:0] dat_cnt;     // Data nibble counter    wire         [2:0] byte_cnt = dat_cnt[3:1];  // Byte counter    wire               nibble_cnt = dat_cnt[0];  // Nibble counter    reg         [31:0] lpc_dat_i;   // Temporary storage for LPC input data.    reg                mem_xfr;     // LPC Memory Transfer (not I/O)    reg                dma_xfr;     // LPC DMA Transfer    reg                fw_xfr;      // LPC Firmware memory read/write    reg          [2:0] xfr_len;     // Number of nibbls for transfer    reg                dma_tc;      // DMA Terminal Count    reg          [2:0] dma_chan;    // DMA Channel    // These buffer enough state to delay the start of the next Wishbone cycle    // until the previous Firmware Write has completed.    reg         [31:0] lpc_adr_reg; // Temporary storage for address received on LPC bus.    reg         [31:0] lpc_dat_o;   // Temporary storage for LPC output data.    reg                lpc_write;   // Holds current LPC transfer direction    reg          [1:0] lpc_tga_o;    reg                got_ack;     // Set when ack has been received from wbm
    assign dma_chan_o = dma_chan;    assign dma_tc_o = dma_tc;        always @(posedge clk_i or negedge nrst_i)    begin        if(~nrst_i)        begin            state <= `LPC_ST_IDLE;            lpc_adr_reg <= 32'h00000000;            lpc_dat_o <= 32'h00000000;            lpc_write <= 1'b0;            lpc_tga_o <= `WB_TGA_MEM;            lad_oe <= 1'b0;            lad_o <= 8'hFF;            lpc_dat_i <= 32'h00000000;            mem_xfr <= 1'b0;            dma_xfr <= 1'b0;            fw_xfr <= 1'b0;            xfr_len <= 3'b000;            dma_tc <= 1'b0;            dma_chan <= 3'b000;        end        else begin            case(state)                `LPC_ST_IDLE:                    begin                        dat_cnt <= 4'h0;                        if(lframe_i) begin                            lad_oe <= 1'b0;                            xfr_len <= 3'b001;                                                            if(lad_i == `LPC_START) begin                                state <= `LPC_ST_CYCTYP;                                lpc_write <= 1'b0;                                fw_xfr <= 1'b0;                                                             end                            else if ((lad_i == `LPC_FW_WRITE) || (lad_i == `LPC_FW_READ)) begin                                state <= `LPC_ST_ADDR;                                lpc_write <= (lad_i == `LPC_FW_WRITE) ? 1'b1 : 1'b0;                                adr_cnt <= 3'b000;                                fw_xfr <= 1'b1;                                dma_xfr <= 1'b0;                                lpc_tga_o <= `WB_TGA_FW;                            end                            else                                state <= `LPC_ST_IDLE;                        end                        else                            state <= `LPC_ST_IDLE;                    end                `LPC_ST_CYCTYP:                    begin                        lpc_write <= (lad_i[3] ? ~lad_i[1] : lad_i[1]);  // Invert we_o if we are doing DMA.                        adr_cnt <= (lad_i[2] ? 3'b000 : 3'b100);                        if(lad_i[3]) begin // dma_xfr                            lpc_tga_o <= `WB_TGA_DMA;                            dma_xfr <= 1'b1;                            mem_xfr <= 1'b0;                            state <= `LPC_ST_CHAN;									                         end                        else if(lad_i[2]) begin // mem_xfr                            lpc_tga_o <= `WB_TGA_MEM;                            dma_xfr <= 1'b0;                            mem_xfr <= 1'b1;                            state <= `LPC_ST_ADDR;                        end                        else begin                            lpc_tga_o <= `WB_TGA_IO;                            dma_xfr <= 1'b0;                            mem_xfr <= 1'b0;                            state <= `LPC_ST_ADDR;                        end                    end                `LPC_ST_ADDR:                    begin                        case(adr_cnt)                            3'h0: lpc_adr_reg[31:28] <= lad_i;                            3'h1: lpc_adr_reg[27:24] <= lad_i;                            3'h2: lpc_adr_reg[23:20] <= lad_i;                            3'h3: lpc_adr_reg[19:16] <= lad_i;                            3'h4: lpc_adr_reg[15:12] <= lad_i;                            3'h5: lpc_adr_reg[11: 8] <= lad_i;                            3'h6: lpc_adr_reg[ 7: 4] <= lad_i;                            3'h7: lpc_adr_reg[ 3: 0] <= lad_i;                        endcase                                                adr_cnt <= adr_cnt + 1;                                                if(adr_cnt == 3'h7) // Last address nibble.                            begin                                if(~fw_xfr)                                    if(lpc_write)                                        state <= `LPC_ST_H_DATA;                                    else                                        state <= `LPC_ST_H_TAR1;                                else    // For firmware read/write, we need to read the MSIZE nibble                                    state <= `LPC_ST_SIZE;                            end                        else                            state <= `LPC_ST_ADDR;                    end                `LPC_ST_CHAN:                    begin                        lpc_adr_reg <= 32'h00000000;      // Address lines not used for DMA.                        dma_tc <= lad_i[3];                        dma_chan <= lad_i[2:0];

⌨️ 快捷键说明

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