dmacntrl.v
来自「VHDLVERILOG语言实现的CARDBUS的IP源码,已经实现现场应用」· Verilog 代码 · 共 454 行 · 第 1/2 页
V
454 行
//------------------------------------------------------------------------------
//
// File : dmacntrl.v
// Last Modification: 06/26/2001
//
// Created In SpDE Version: SpDE 8.22
// Author : Richard Yuan, QuickLogic Corporation
// Copyright (C) 2001, Licensed Customers of QuickLogic may copy and modify
// this file for use in designing with QuickLogic devices only.
//
// Description : DMA Controller Reference Design for 5332/5432.
// See the QuickPCI User's Guide for a detailed description of functionality.
// Note that this DMA Controller Reference Design is different from that of 5032/5232.
//
// Hierarchy:
// This file represents the dmacntrl block in pci5432_280.sch.
//
// History:
// Date Author Version
// 02/09/01 Richard Yuan 1.0
// - Initial release. Modifed from dmacntrl.v in 5032 ref design.
// 06/26/01 Richard Yuan 1.1
// - Header reorganized to conform to coding standard.
//
//------------------------------------------------------------------------------
`timescale 1ns/1ns
`include "dcount8.v"
`include "dcount16.v"
module dmacntrl (
PCI_reset, // PCI Reset, active high & asynchronous
PCI_clk, // PCI Clk (33 MHz)
Usr_CBE, // Registered PCI CBE signals [3:0]
Usr_Ad, // PCI Target Address [9:2]
Usr_WrData, // Registered PCI Data Signals [31:0]
Usr_RdDataIn, // Data for User Reads not decoded within this block [31:0]
Mst_Tabort_Det, // Target aborting transfer this cycle
Mst_Xfer_D1, // Delayed XFER Detected on PCI
Mst_TTO_Det, // Target did not assert DEVSEL in time
Usr_Write, // Write Data on PCI pins addressed to DMA Registers
IncrAddr, //Address increment signal, used to enable writing to dma regs.
BusMstEn, // PCI Config Command Bit 2 (bus mastering enabled)
RdRdy, // Read FIFO has room for data from PCI
WrRdy, // Write FIFO is ready to send data to PCI
LastWr, // End of Packet Signal from FIFO
Mst_WrBurst_Done, // Write Pipeline is clear (including output register)
Mst_RdBurst_Done, // Read Pipeline is clear
Mst_WrData_Rdy, // Write Pipeline is ready for new data
Mst_BE_FIFO, // Byte-enables from the BE FIFO
Mst_RdData_Valid, // Data strobe from PCI core for master read
Mst_RdAd, // Decoded for Reads of DMA registers [31:0]
Mst_WrAd, // Decoded for Reads of DMA registers [31:0]
Usr_RdData, // For Target Reads of DMA registers [31:0]
Mst_WrData_Valid, // In active write state (not flushing pipeline)
DMAWrEn, // Software controlled enable for the write FIFO
DMARdEn, // Software controlled enable for the read FIFO
LocalEn, // Software controlled enable for back-end target accesses
Mst_Burst_Req, // Tells master to assert REQN
Mst_One_Read, // one read remains in burst
Mst_Two_Reads, // two reads remain in burst
MstRdAd_Sel, // Address for Master Read Address has been selected
MstWrAd_Sel, // Address for Master Write Address has been selected
Mst_LatCntEn, // Enables Latency Counter for Master Transactions
PCI_Cmd, // Specifies the PCI Command to Use [3:0]
BEfifo, // Push signal for the BE FIFO
Mst_BE_Sel, // Selects which byte-enable mode
Mst_BE, // Byte-enable signal for master transactions [3:0]
Mst_Rd_Term_Sel, // Master read termination mode
WD_Reg, // Master data reg output [31:0]
Mst_Data_Sel // Selects whether FIFO or WD_Reg is read/written
);
input PCI_reset,PCI_clk, Mst_Xfer_D1;
input BusMstEn, Usr_Write, IncrAddr;
input [9:2] Usr_Ad;
input [3:0] Usr_CBE;
input [31:0] Usr_WrData, Usr_RdDataIn;
input Mst_Tabort_Det, Mst_TTO_Det, RdRdy, WrRdy;
input LastWr, Mst_WrBurst_Done, Mst_RdBurst_Done, Mst_WrData_Rdy;
input [3:0] Mst_BE_FIFO;
input Mst_RdData_Valid;
output Mst_Burst_Req, Mst_WrData_Valid;
output [31:0] Mst_RdAd, Mst_WrAd, Usr_RdData;
output DMAWrEn, DMARdEn, LocalEn, Mst_LatCntEn;
output Mst_One_Read, Mst_Two_Reads, MstRdAd_Sel, MstWrAd_Sel;
output [3:0] PCI_Cmd;
output BEfifo;
output [3:0] Mst_BE;
output Mst_BE_Sel, Mst_Rd_Term_Sel;
output [31:0] WD_Reg;
output Mst_Data_Sel;
parameter Burst_Length = 255; // Set to desired PCI burst length, up to 255
// DMA Burst State Machine (one-hot)
parameter idle = 5'b00001;
parameter dma_wr = 5'b00010;
parameter dma_wr_wt = 5'b00100;
parameter dma_rd = 5'b01000;
parameter dma_rd_wt = 5'b10000;
parameter idle_bt=0;
parameter dma_wr_bt=1;
parameter dma_wr_wt_bt=2;
parameter dma_rd_bt=3;
parameter dma_rd_wt_bt=4;
reg [4:0] DMASm /* synthesis syn_encoding = "onehot" */;
reg Mst_RdBE_Load_Done;
wire [7:0] Burst_Cnt2;
wire Dec_BCnt2, BCnt2_eq_1;
wire PCI_reset,PCI_clk;
wire [9:2] Usr_Ad;
wire [3:0] Usr_CBE;
wire [31:0] Usr_WrData, Mst_RdAd, Mst_WrAd, DMACntReg, DMACtrlStat;
wire [15:0] DMARdCnt,DMAWrCnt;
wire [7:0] Burst_Cnt, RdBCnt, WrBCnt, Init_BCnt;
wire BCnt_eq_1, BCnt_eq_2, BCnt_eq_3, Mst_One_Read, Mst_Two_Reads;
wire Usr_Write, IncrAddr, PCIWrEn, PCIRdEn;
wire RdRdy, WrRdy, LastWr, Ld_BCnt, LdWrCnt, LdRdCnt;
wire LdRdAdrCnt, LdWrAdrCnt, DecDMARdCnt, Dec_BCnt, IncWrAdr, IncRdAdr;
wire Mst_RdMode, Mst_WrMode;
wire [3:0] Mst_BE_FIFO;
wire Mst_Data_Sel;
reg [31:0] Usr_RdData;
reg [3:0] Mst_RdCmd;
reg [2:0] Mst_WrCmd;
reg MstRdAd_Sel, MstWrAd_Sel;
reg Mst_WrData_Valid, WrCnt0, RdCnt0;
reg DMAWrEn, DMARdEn, DMAWrErr, DMARdErr, LocalEn, Mst_LatCntEn;
reg Mst_Burst_Req, DecDMAWrCnt;
reg WrCtrl, WrRdAdr, WrWrAdr, WrDMACnt, WrDReg, BEfifo;
reg [3:0] PCI_Cmd;
reg [3:0] Mst_BE, Mst_RdBE, Mst_WrBE;
reg Mst_WrBE_Sel, Mst_RdBE_Sel, Mst_Rd_Term_Sel;
reg [31:0] Mst_D_Reg;
reg Mst_WrData_Sel, Mst_RdData_Sel;
// PCI command decoded from various registers
// This decoding process is to be compatible with 5032/5232 reference design
// More straightforward approach may be used to simplify logic
always @(Mst_RdMode or Mst_WrMode or Mst_RdCmd or Mst_WrCmd) begin
if (Mst_RdMode) begin
if (~Mst_RdCmd[3])
case (Mst_RdCmd[1:0])
2'b00, 2'b01: PCI_Cmd <= 4'b0110;
2'b10: PCI_Cmd <= 4'b1110;
2'b11: PCI_Cmd <= 4'b1100;
default: PCI_Cmd <= 4'b0110;
endcase
else PCI_Cmd <= {Mst_RdCmd[2:0], 1'b0};
end else if (Mst_WrMode)
if (Mst_WrCmd) begin
if (Mst_WrCmd == 3'b011) PCI_Cmd <= 4'b0001;
else PCI_Cmd <= {Mst_WrCmd, 1'b1};
end
else PCI_Cmd <= 4'b0111;
else PCI_Cmd <= 4'b0110;
end
// Master byte-enable mode generation
always @(Mst_RdMode or Mst_RdBE_Sel or Mst_WrBE_Sel or Mst_RdBE or Mst_WrBE or Mst_BE_FIFO) begin
if (Mst_RdMode) begin
if (Mst_RdBE_Sel) Mst_BE <= Mst_BE_FIFO;
else Mst_BE <= Mst_RdBE;
end else begin
if (Mst_WrBE_Sel) Mst_BE <= Mst_BE_FIFO;
else Mst_BE <= Mst_WrBE;
end
end
// Data and BE source/destination selection for master transactions
assign Mst_Data_Sel = Mst_RdMode ? Mst_RdData_Sel : Mst_WrData_Sel;
assign Mst_BE_Sel = Mst_RdMode ? Mst_RdBE_Sel : Mst_WrBE_Sel;
// DMA Register Read Addressing
always @(Usr_Ad or DMACtrlStat or DMACntReg or Usr_RdDataIn or Mst_D_Reg)
casex (Usr_Ad)
8'b0100000x: Usr_RdData <= DMACntReg; // address 0x100
8'b0100001x: Usr_RdData <= DMACtrlStat; // address 0x10C
8'b01000111: Usr_RdData <= Mst_D_Reg; // address 0x11C
default: Usr_RdData <= Usr_RdDataIn;
endcase
always @(Usr_Ad) begin
MstWrAd_Sel <= 1'b0;
MstRdAd_Sel <= 1'b0;
case (Usr_Ad)
8'b01000001: MstWrAd_Sel <= 1'b1; // address 0x104
8'b01000010: MstRdAd_Sel <= 1'b1; // address 0x108
endcase
end
// DMA Register Write Addressing
always @(Usr_Write or IncrAddr or Usr_Ad) begin
WrCtrl <= 0;
WrRdAdr <= 0;
WrWrAdr <= 0;
WrDMACnt <= 0;
WrDReg <= 0;
BEfifo <= 0;
if (Usr_Write && IncrAddr)
casex (Usr_Ad)
8'b01000011: WrCtrl <= 1; // address 0x10C
8'b01000010: WrRdAdr <= 1; // address 0x108
8'b01000001: WrWrAdr <= 1; // address 0x104
8'b01000000: WrDMACnt <= 1; // address 0x100
8'b01000111: WrDReg <= 1; // address 0x11C
8'b10xxxxxx: BEfifo <= 1; // address 0x2XX
endcase
end
// Master data register so that data don't have to always come from/go to FIFO
always @(posedge PCI_clk or posedge PCI_reset)
if (PCI_reset) Mst_D_Reg <= 32'b0;
else if ((Mst_RdData_Valid & Mst_RdData_Sel) || WrDReg)
Mst_D_Reg <= Usr_WrData;
wire [31:0] WD_Reg = Mst_D_Reg;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?