dmaregrd.v

来自「VHDLVERILOG语言实现的CARDBUS的IP源码,已经实现现场应用」· Verilog 代码 · 共 158 行

V
158
字号
//------------------------------------------------------------------------------
//
// File : dmaregrd.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 : This is a block in the QL5(3/4)32-33 programmable logic region.
//	It contains the following sections:
//		clock frequency control registers
//		DMA performance measurement registers
//		programmable retry/wait-state control registers
//		some target memory
//
// Hierarchy:
//	This file represents the dmaregrd block in pci5432_280.sch.
//
// History:	
//	Date	        Author					Version
//	01/25/01		Richard Yuan			1.0
//		- Initial release. Modifed from dmaregrd.v in 5032 ref design.
//  06/26/01		Richard Yuan			1.1
//		- Header reorganized to conform to coding standard.
//
//------------------------------------------------------------------------------


`include "r128a8.v"

module dmaregrd (clk,clr,DMAWrEn, PCI_data, CBE, DMARdEn,adr,dataout,PCI_Wr, clkspd, IncrAddr, LoadAddr, ledcntrl, led, Usr_Rdy, Usr_Stop);

input clk, clr, DMAWrEn, DMARdEn, PCI_Wr;
input [9:2] adr;
input [31:0] PCI_data;
input [3:0] CBE;
input IncrAddr, LoadAddr;
output [31:0] dataout;
output [2:0] clkspd;
output ledcntrl;
output [7:0] led;
output Usr_Rdy, Usr_Stop;

reg [19:0] perfcount;
reg [31:0] dataout; 
reg DMARdWr, ClkSpdHit, ledcntrl, TControlHit;
reg [2:0] clkspd, StopReg, WaitReg, StopCount, WaitCount, RetryCount;
reg [7:0] led;
wire PerfCntLd;
wire [31:0] ram_read_data;
wire ram0_we, ram1_we, ram2_we, ram3_we;


// Keep last state of DMARxEn and DMATxEn
always @(posedge clk) DMARdWr <= DMAWrEn || DMARdEn;

// Initialize Counter as soon as DMARxEn or DMATxEn is set to 1
assign PerfCntLd = ~DMARdWr && (DMAWrEn || DMARdEn);

always @(posedge clk or posedge clr)
	if (clr) perfcount <= 20'h00000;
	else if (PerfCntLd) perfcount <= 20'h00000;
	else if (DMARdWr) perfcount <= perfcount + 1;

always @(adr or perfcount or clkspd or ram_read_data or led or ledcntrl or RetryCount or StopReg or WaitReg)
	case (adr)
		8'b01000100: dataout <= perfcount;		// address 0x110
		8'b01000101: dataout <= clkspd;			// address 0x114
		8'b01000110: dataout <= {5'b0, RetryCount, 1'b0, StopReg, 1'b0, WaitReg, 7'b0, ledcntrl, led[7:0]};	// address 0x118
		default: dataout <= ram_read_data;
		endcase

always @(adr) begin
	ClkSpdHit <= 1'b0;
	TControlHit <= 1'b0;
	case (adr)
		8'b01000101: ClkSpdHit <= 1'b1;	// address 0x114
		8'b01000110: TControlHit <= 1'b1;	// address 0x118
		endcase
	end

always @(posedge clk or posedge clr)
	if (clr) begin
		clkspd <= 3'b110; // defaults to 42 MHz (3X clock)
		end
	else if (IncrAddr && PCI_Wr && ClkSpdHit && ~CBE[0]) begin
		clkspd <= PCI_data[2:0];
		end

always @(posedge clk or posedge clr)
	if (clr) begin
		ledcntrl <= 1'b0; // defaults to FIFO/buffer status
		led <= 8'h00;
		end
	else begin
		if (IncrAddr && PCI_Wr && TControlHit && ~CBE[0]) led[7:0] <= PCI_data[7:0];
		if (IncrAddr && PCI_Wr && TControlHit && ~CBE[1]) ledcntrl <= PCI_data[8];
		end

// Reg to remember if Usr_Rdy has been asserted
reg Usr_Rdy_asserted;
// Programmable Wait State Control
always @(posedge clk or posedge clr)
	if (clr) begin
		WaitCount <= 3'b000;
		WaitReg <= 3'b000;
		Usr_Rdy_asserted <= 1'b0;
		end
	else begin
		if (LoadAddr || IncrAddr || (PCI_Wr & Usr_Rdy)) WaitCount <= 0;
		else if (WaitCount != WaitReg) WaitCount <= WaitCount + 1;
		if (IncrAddr && PCI_Wr && TControlHit && ~CBE[2]) WaitReg <= PCI_data[18:16];
		if (LoadAddr || IncrAddr) Usr_Rdy_asserted <= 1'b0;
		else if (Usr_Rdy) Usr_Rdy_asserted <= 1'b1;
		end

// Usr_Rdy generated from comparing WaitCount and WaitReg
assign Usr_Rdy = PCI_Wr ? (WaitCount == WaitReg) && ((~Usr_Rdy_asserted) || (WaitReg == 3'b000)) : (WaitCount == WaitReg);

// Programmable Stop Cycle Control
always @(posedge clk or posedge clr)
	if (clr) begin
		StopCount <= 3'b000;
		StopReg <= 3'b000;
		end
	else begin
		if (LoadAddr || Usr_Stop) StopCount <= 0;
		else if (~(StopCount == StopReg) && IncrAddr) StopCount <= StopCount + 1;
		if (IncrAddr && PCI_Wr && TControlHit && ~CBE[2]) StopReg <= PCI_data[22:20];
		end

// Programmable Retry Control
always @(posedge clk or posedge clr)
	if (clr) begin
		RetryCount <= 3'b000;
		end
	else begin
		if (IncrAddr && PCI_Wr && TControlHit && ~CBE[3]) RetryCount <= PCI_data[26:24];
		else if (~(RetryCount == 3'b000) && LoadAddr) RetryCount <= RetryCount - 1;
		end

assign Usr_Stop = (StopReg == 3'b000) ? ~(RetryCount == 3'b000) : (StopCount == StopReg);


assign ram0_we = ~CBE[0] && IncrAddr && PCI_Wr;
assign ram1_we = ~CBE[1] && IncrAddr && PCI_Wr;
assign ram2_we = ~CBE[2] && IncrAddr && PCI_Wr;
assign ram3_we = ~CBE[3] && IncrAddr && PCI_Wr; 

r128a8 target_ram0 (.wa(adr[8:2]),.ra(adr[8:2]),.wd(PCI_data[7:0]),.rd(ram_read_data[7:0]),.we(ram0_we),.wclk(clk));
r128a8 target_ram1 (.wa(adr[8:2]),.ra(adr[8:2]),.wd(PCI_data[15:8]),.rd(ram_read_data[15:8]),.we(ram1_we),.wclk(clk));
r128a8 target_ram2 (.wa(adr[8:2]),.ra(adr[8:2]),.wd(PCI_data[23:16]),.rd(ram_read_data[23:16]),.we(ram2_we),.wclk(clk));
r128a8 target_ram3 (.wa(adr[8:2]),.ra(adr[8:2]),.wd(PCI_data[31:24]),.rd(ram_read_data[31:24]),.we(ram3_we),.wclk(clk));

endmodule

⌨️ 快捷键说明

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