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 + -
显示快捷键?