📄 wb_lpc_host.v
字号:
////////////////////////////////////////////////////////////////////////// //////// $Id: wb_lpc_host.v,v 1.4 2008-07-26 19:15:31 hharte Exp $ //////// wb_lpc_host.v - Wishbone Slave to LPC Host 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_host(clk_i, nrst_i, wbs_adr_i, wbs_dat_o, wbs_dat_i, wbs_sel_i, wbs_tga_i, wbs_we_i, wbs_stb_i, wbs_cyc_i, wbs_ack_o, wbs_err_o, dma_chan_i, dma_tc_i, lframe_o, lad_i, lad_o, lad_oe); // Wishbone Slave Interface input clk_i; input nrst_i; // Active low reset. input [31:0] wbs_adr_i; output [31:0] wbs_dat_o; input [31:0] wbs_dat_i; input [3:0] wbs_sel_i; input [1:0] wbs_tga_i; input wbs_we_i; input wbs_stb_i; input wbs_cyc_i; output reg wbs_ack_o; output reg wbs_err_o; // LPC Master Interface output reg lframe_o; // LPC Frame output (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 input [2:0] dma_chan_i; // DMA Channel input dma_tc_i; // DMA Terminal Count reg [13:0] state; // Current state reg [2:0] adr_cnt; // Address nibbe counter reg [3:0] dat_cnt; // Data nibble counter reg [2:0] xfr_len; // Number of nibbls for transfer 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 input word. // // generate wishbone register signals wire wbs_acc = wbs_cyc_i & wbs_stb_i; // Wishbone access wire wbs_wr = wbs_acc & wbs_we_i; // Wishbone write access // Memory Cycle (tga== 1'b00) is bit 2=1 for LPC Cycle Type. wire mem_xfr = (wbs_tga_i == `WB_TGA_MEM); wire dma_xfr = (wbs_tga_i == `WB_TGA_DMA); wire fw_xfr = (wbs_tga_i == `WB_TGA_FW); assign wbs_dat_o[31:0] = lpc_dat_i; always @(posedge clk_i or negedge nrst_i) if(~nrst_i) begin state <= `LPC_ST_IDLE; lframe_o <= 1'b0; wbs_ack_o <= 1'b0; wbs_err_o <= 1'b0; lad_oe <= 1'b0; lad_o <= 4'b0; adr_cnt <= 3'b0; dat_cnt <= 4'h0; xfr_len <= 3'b000; lpc_dat_i <= 32'h00000000; end else begin case(state) `LPC_ST_IDLE: begin wbs_ack_o <= 1'b0; wbs_err_o <= 1'b0; lframe_o <= 1'b0; dat_cnt <= 4'h0; if(wbs_acc) // Wishbone access starts LPC transaction state <= `LPC_ST_START; else state <= `LPC_ST_IDLE; end `LPC_ST_START: begin lframe_o <= 1'b1; if(~fw_xfr) begin // For Memory and I/O Cycles lad_o <= `LPC_START; state <= `LPC_ST_CYCTYP; end else begin // Firmware Read and Write Cycles if(wbs_wr) lad_o <= `LPC_FW_WRITE; else lad_o <= `LPC_FW_READ; state <= `LPC_ST_ADDR; end lad_oe <= 1'b1; adr_cnt <= ((mem_xfr | fw_xfr) ? 3'b000 : 3'b100); end `LPC_ST_CYCTYP: begin lframe_o <= 1'b0; lad_oe <= 1'b1; if(~dma_xfr) begin lad_o <= {1'b0,mem_xfr,wbs_wr,1'b0}; // Cycle Type/Direction for I/O or MEM state <= `LPC_ST_ADDR; end else // it is DMA begin lad_o <= {1'b1,1'b0,~wbs_wr,1'b0}; // Cycle Type/Direction for DMA, r/w is inverted for DMA state <= `LPC_ST_CHAN; end end `LPC_ST_ADDR: // Output four nubbles of address. begin lframe_o <= 1'b0; // In case we came here from a Firmware cycle, which skips CYCTYP. // The LPC Bus Address is sent across the bus a nibble at a time; // however, the most significant nibble is sent first. For firmware and // memory cycles, the address is 32-bits. Actually, for firmware accesses, // the most significant nibble is known as the IDSEL field. For I/O, // the address is only 16-bits wide. case(adr_cnt) 3'h0: lad_o <= wbs_adr_i[31:28]; 3'h1: lad_o <= wbs_adr_i[27:24]; 3'h2: lad_o <= wbs_adr_i[23:20]; 3'h3: lad_o <= wbs_adr_i[19:16]; 3'h4: lad_o <= wbs_adr_i[15:12]; 3'h5: lad_o <= wbs_adr_i[11:8]; 3'h6: lad_o <= wbs_adr_i[7:4]; 3'h7: lad_o <= wbs_adr_i[3:0]; endcase
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -