📄 wb_lpc_periph.v
字号:
////////////////////////////////////////////////////////////////////////// //////// $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 + -