OpenCores
URL https://opencores.org/ocsvn/pci/pci/trunk

Subversion Repositories pci

[/] [pci/] [tags/] [rel_5/] [bench/] [verilog/] [wb_slave_behavioral.v] - Rev 15

Go to most recent revision | Compare with Previous | Blame | View Log

//////////////////////////////////////////////////////////////////////
////                                                              ////
////  File name: wb_slave_behavioral.v                            ////
////                                                              ////
////  This file is part of the "PCI bridge" project               ////
////  http://www.opencores.org/cores/pci/                         ////
////                                                              ////
////  Author(s):                                                  ////
////      - Tadej Markovic, tadej@opencores.org                   ////
////                                                              ////
////  All additional information is avaliable in the README.txt   ////
////  file.                                                       ////
////                                                              ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
////                                                              ////
//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org       ////
////                                                              ////
//// 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                     ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
//
 
`include "pci_testbench_defines.v"
`include "timescale.v"
module WB_SLAVE_BEHAVIORAL
(
	CLK_I,
	RST_I,
	ACK_O,
	ADR_I,
	CYC_I,
	DAT_O,
	DAT_I,
	ERR_O,
	RTY_O,
	SEL_I,
	STB_I,
	WE_I,
	CAB_I
);
 
/*----------------------------------------------------------------------------------------------------------------------
WISHBONE signals
----------------------------------------------------------------------------------------------------------------------*/
input					CLK_I ;
input					RST_I ;
output					ACK_O ;
input	`WB_ADDR_TYPE	ADR_I ;
input					CYC_I ;
output	`WB_DATA_TYPE	DAT_O ;
input	`WB_DATA_TYPE	DAT_I ;
output					ERR_O ;
output					RTY_O ;
input	`WB_SEL_TYPE	SEL_I ;
input					STB_I ;
input					WE_I ;
input					CAB_I ;
 
//reg				ACK_O ;
//reg				ERR_O ;
//reg				RTY_O ;
reg		[31:0]	DAT_O ;
 
/*----------------------------------------------------------------------------------------------------------------------
Asynchronous dual-port RAM signals for storing and fetching the data
----------------------------------------------------------------------------------------------------------------------*/
reg 	[31:0] 	wb_memory [0:1023] ; // data for WB memory - 16 LSB addresses are connected
reg		[31:0]	mem_wr_data_out ;
reg		[31:0]	mem_rd_data_in ;
 
/*----------------------------------------------------------------------------------------------------------------------
Maximum values for WAIT and RETRY counters and which response !!!
----------------------------------------------------------------------------------------------------------------------*/
reg		[2:0]	a_e_r_resp ; 		// tells with which cycle_termination_signal must wb_slave respond !
reg				wait_cyc ;
reg		[7:0]	max_retry ;
 
// assign registers to default state while in reset
always@(RST_I)
begin
    if (RST_I)
    begin
        a_e_r_resp	<= 3'b000 ; // do not respond
    	wait_cyc	<= 1'b0 ;	// no wait cycles
        max_retry	<= 8'h0 ;	// no retries
    end
end //reset
 
task cycle_response ;
	input [2:0]		ack_err_rty_resp ;	// acknowledge, error or retry response input flags
	input 			wait_cycles ;		// if wait cycles before each data termination cycle (ack, err or rty)
	input [7:0]		retry_cycles ;		// noumber of retry cycles before acknowledge cycle
begin
    // assign values
    a_e_r_resp	<= #1 ack_err_rty_resp ;
	wait_cyc	<= #1 wait_cycles ;
    max_retry	<= #1 retry_cycles ;
end
endtask // cycle_response
 
/*----------------------------------------------------------------------------------------------------------------------
Internal signals and logic
----------------------------------------------------------------------------------------------------------------------*/
reg				calc_ack ;
reg				calc_err ;
reg				calc_rty ;
 
reg		[7:0]	retry_cnt ;
reg		[7:0]	retry_num ;
reg				retry_expired ;
reg				retry_rst ;
 
// RESET retry counter
always@(posedge RST_I or posedge CLK_I)
begin
	if (RST_I)
		retry_rst <= 1'b1 ;
	else
		retry_rst <= calc_ack || calc_err ;
end
 
// Retry counter
always@(posedge retry_rst or negedge calc_rty)
begin
	if (retry_rst)
		retry_cnt <= #`FF_DELAY 8'h00 ;
	else
		retry_cnt <= #`FF_DELAY retry_num ;
end
always@(retry_cnt or max_retry)
begin
	if (retry_cnt < max_retry)
	begin
		retry_num = retry_cnt + 1'b1 ;
		retry_expired = #10 1'b0 ;
	end
	else
	begin
		retry_num = retry_cnt ;
		retry_expired = #10 1'b1 ;
	end
end
 
reg		[1:0]	wait_cnt ;
reg		[1:0]	wait_num ;
reg				wait_expired ;
reg				reset_wait ;
 
always@(posedge RST_I or posedge CLK_I)
begin
	if (RST_I)
		reset_wait <= #`FF_DELAY 1'b1 ;
	else
		reset_wait <= #`FF_DELAY (wait_expired || ~STB_I) ;
end
 
// Wait counter
always@(posedge reset_wait or posedge CLK_I)
begin
	if (reset_wait)
		wait_cnt <= #`FF_DELAY 4'h0 ;
	else
		wait_cnt <= #`FF_DELAY wait_num ;
end
always@(wait_cnt or wait_cyc or STB_I or a_e_r_resp or retry_expired)
begin
	if ((wait_cyc) && (STB_I))
	begin
		if (wait_cnt < 2'h2)
		begin
			wait_num = wait_cnt + 1'b1 ;
			wait_expired = 1'b0 ;
			calc_ack = 1'b0 ;
			calc_err = 1'b0 ;
			calc_rty = 1'b0 ;
		end
		else
		begin
			wait_num = wait_cnt ;
			wait_expired = 1'b1 ;
			if (a_e_r_resp == 3'b100)
			begin
				calc_ack = 1'b1 ;
				calc_err = 1'b0 ;
				calc_rty = 1'b0 ;
			end
			else
			if (a_e_r_resp == 3'b010)
			begin
				calc_ack = 1'b0 ;
				calc_err = 1'b1 ;
				calc_rty = 1'b0 ;
			end
			else
			if (a_e_r_resp == 3'b001)
			begin
				calc_err = 1'b0 ;
				if (retry_expired)
				begin
					calc_ack = 1'b1 ;
					calc_rty = 1'b0 ;
				end
				else
				begin
					calc_ack = 1'b0 ;
					calc_rty = 1'b1 ;
				end
			end
			else
			begin
				calc_ack = 1'b0 ;
				calc_err = 1'b0 ;
				calc_rty = 1'b0 ;
			end
		end
	end
	else
	if ((~wait_cyc) && (STB_I))
	begin
		wait_num = 2'h0 ;
		wait_expired = 1'b1 ;
		if (a_e_r_resp == 3'b100)
		begin
			calc_ack = 1'b1 ;
			calc_err = 1'b0 ;
			calc_rty = 1'b0 ;
		end
		else
		if (a_e_r_resp == 3'b010)
		begin
			calc_ack = 1'b0 ;
			calc_err = 1'b1 ;
			calc_rty = 1'b0 ;
		end
		else
		if (a_e_r_resp == 3'b001)
		begin
			calc_err = 1'b0 ;
			if (retry_expired)
			begin
				calc_ack = 1'b1 ;
				calc_rty = 1'b0 ;
			end
			else
			begin
				calc_ack = 1'b0 ;
				calc_rty = 1'b1 ;
			end
		end
		else
		begin
			calc_ack = 1'b0 ;
			calc_err = 1'b0 ;
			calc_rty = 1'b0 ;
		end
	end
	else
	begin
		wait_num = 2'h0 ;
		wait_expired = 1'b0 ;
		calc_ack = 1'b0 ;
		calc_err = 1'b0 ;
		calc_rty = 1'b0 ;
	end
end
 
wire	rd_sel = (CYC_I && STB_I && ~WE_I) ;
wire	wr_sel = (CYC_I && STB_I && WE_I) ;
 
// Generate cycle termination signals
assign	ACK_O = calc_ack && STB_I ;
assign	ERR_O = calc_err && STB_I ;
assign	RTY_O = calc_rty && STB_I ;
 
// Assign address to asynchronous memory
always@(ADR_I or RST_I)
begin
	if (RST_I) // this is added because at start of test bench we need address change in order to get data!
		mem_rd_data_in = 32'hxxxx_xxxx ;
	else
		mem_rd_data_in = wb_memory[ADR_I[11:2]] ;
end
 
// assign outputs to unknown state while in reset
always@(RST_I)
begin
    if (RST_I)
    begin
		DAT_O <= 32'hxxxx_xxxx ;
    end
end //reset
 
// Data input/output interface
always@(rd_sel or wr_sel or mem_rd_data_in or DAT_I or SEL_I or mem_wr_data_out)
begin
	if (rd_sel)
	begin
		DAT_O = mem_rd_data_in ;
	end
end
always@(posedge CLK_I)
begin
    if (wr_sel)
    begin
        mem_wr_data_out         = wb_memory[ADR_I[11:2]] ;
 
        if ( SEL_I[3] )
            mem_wr_data_out[31:24] = DAT_I[31:24] ;
 
        if ( SEL_I[2] )
            mem_wr_data_out[23:16] = DAT_I[23:16] ;
 
        if ( SEL_I[1] )
            mem_wr_data_out[15: 8] = DAT_I[15: 8] ;
 
        if ( SEL_I[0] )
            mem_wr_data_out[ 7: 0] = DAT_I[ 7: 0] ;
 
        wb_memory[ADR_I[11:2]] <= mem_wr_data_out ;
    end
end
 
endmodule
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.