URL
https://opencores.org/ocsvn/spacewiresystemc/spacewiresystemc/trunk
Subversion Repositories spacewiresystemc
[/] [spacewiresystemc/] [trunk/] [altera_work/] [spw_fifo_ulight/] [ulight_fifo/] [synthesis/] [submodules/] [altera_merlin_slave_translator.sv] - Rev 40
Compare with Previous | Blame | View Log
// (C) 2001-2017 Intel Corporation. All rights reserved.// Your use of Intel Corporation's design tools, logic functions and other// software and tools, and its AMPP partner logic functions, and any output// files from any of the foregoing (including device programming or simulation// files), and any associated documentation or information are expressly subject// to the terms and conditions of the Intel Program License Subscription// Agreement, Intel FPGA IP License Agreement, or other applicable// license agreement, including, without limitation, that your use is for the// sole purpose of programming logic devices manufactured by Intel and sold by// Intel or its authorized distributors. Please refer to the applicable// agreement for further details.// $Id: //acds/rel/17.1std/ip/merlin/altera_merlin_slave_translator/altera_merlin_slave_translator.sv#1 $// $Revision: #1 $// $Date: 2017/07/30 $// $Author: swbranch $// -------------------------------------// Merlin Slave Translator//// Translates Universal Avalon MM Slave// to any Avalon MM Slave// -------------------------------------////Notable Note: 0 AV_READLATENCY is not allowed and will be converted to a 1 cycle readlatency in all cases but one//If you declare a slave with fixed read timing requirements, the readlatency of such a slave will be allowed to be zero//The key feature here is that no same cycle turnaround data is processed through the fabric.//import avalon_utilities_pkg::*;`timescale 1 ns / 1 nsmodule altera_merlin_slave_translator #(parameter//WidthsAV_ADDRESS_W = 32,AV_DATA_W = 32,AV_BURSTCOUNT_W = 4,AV_BYTEENABLE_W = 4,UAV_BYTEENABLE_W = 4,//Read LatencyAV_READLATENCY = 1,//TimingAV_READ_WAIT_CYCLES = 0,AV_WRITE_WAIT_CYCLES = 0,AV_SETUP_WAIT_CYCLES = 0,AV_DATA_HOLD_CYCLES = 0,//Optional Port DeclarationsUSE_READDATAVALID = 1,USE_WAITREQUEST = 1,USE_READRESPONSE = 0,USE_WRITERESPONSE = 0,//Variable AddressingAV_SYMBOLS_PER_WORD = 4,AV_ADDRESS_SYMBOLS = 0,AV_BURSTCOUNT_SYMBOLS = 0,BITS_PER_WORD = clog2_plusone(AV_SYMBOLS_PER_WORD - 1),UAV_ADDRESS_W = 38,UAV_BURSTCOUNT_W = 10,UAV_DATA_W = 32,AV_CONSTANT_BURST_BEHAVIOR = 0,UAV_CONSTANT_BURST_BEHAVIOR = 0,CHIPSELECT_THROUGH_READLATENCY = 0,// Tightly-Coupled OptionsUSE_UAV_CLKEN = 0,AV_REQUIRE_UNALIGNED_ADDRESSES = 0) (// -------------------// Clock & Reset// -------------------input wire clk,input wire reset,// -------------------// Universal Avalon Slave// -------------------input wire [UAV_ADDRESS_W - 1 : 0] uav_address,input wire [UAV_DATA_W - 1 : 0] uav_writedata,input wire uav_write,input wire uav_read,input wire [UAV_BURSTCOUNT_W - 1 : 0] uav_burstcount,input wire [UAV_BYTEENABLE_W - 1 : 0] uav_byteenable,input wire uav_lock,input wire uav_debugaccess,input wire uav_clken,output logic uav_readdatavalid,output logic uav_waitrequest,output logic [UAV_DATA_W - 1 : 0] uav_readdata,output logic [1:0] uav_response,// input wire uav_writeresponserequest,output logic uav_writeresponsevalid,// -------------------// Customizable Avalon Master// -------------------output logic [AV_ADDRESS_W - 1 : 0] av_address,output logic [AV_DATA_W - 1 : 0] av_writedata,output logic av_write,output logic av_read,output logic [AV_BURSTCOUNT_W - 1 : 0] av_burstcount,output logic [AV_BYTEENABLE_W - 1 : 0] av_byteenable,output logic [AV_BYTEENABLE_W - 1 : 0] av_writebyteenable,output logic av_begintransfer,output wire av_chipselect,output logic av_beginbursttransfer,output logic av_lock,output wire av_clken,output wire av_debugaccess,output wire av_outputenable,input logic [AV_DATA_W - 1 : 0] av_readdata,input logic av_readdatavalid,input logic av_waitrequest,input logic [1:0] av_response,// output logic av_writeresponserequest,input wire av_writeresponsevalid);function integer clog2_plusone;input [31:0] Depth;integer i;begini = Depth;for(clog2_plusone = 0; i > 0; clog2_plusone = clog2_plusone + 1)i = i >> 1;endendfunctionfunction integer max;//returns the larger of two passed argumentsinput [31:0] one;input [31:0] two;if(one > two)max=one;elsemax=two;endfunction // intlocalparam AV_READ_WAIT_INDEXED = (AV_SETUP_WAIT_CYCLES + AV_READ_WAIT_CYCLES);localparam AV_WRITE_WAIT_INDEXED = (AV_SETUP_WAIT_CYCLES + AV_WRITE_WAIT_CYCLES);localparam AV_DATA_HOLD_INDEXED = (AV_WRITE_WAIT_INDEXED + AV_DATA_HOLD_CYCLES);localparam LOG2_OF_LATENCY_SUM = max(clog2_plusone(AV_READ_WAIT_INDEXED + 1),clog2_plusone(AV_DATA_HOLD_INDEXED + 1));localparam BURSTCOUNT_SHIFT_SELECTOR = AV_BURSTCOUNT_SYMBOLS ? 0 : BITS_PER_WORD;localparam ADDRESS_SHIFT_SELECTOR = AV_ADDRESS_SYMBOLS ? 0 : BITS_PER_WORD;localparam ADDRESS_HIGH = ( UAV_ADDRESS_W > AV_ADDRESS_W + ADDRESS_SHIFT_SELECTOR ) ?AV_ADDRESS_W :UAV_ADDRESS_W - ADDRESS_SHIFT_SELECTOR;localparam BURSTCOUNT_HIGH = ( UAV_BURSTCOUNT_W > AV_BURSTCOUNT_W + BURSTCOUNT_SHIFT_SELECTOR ) ?AV_BURSTCOUNT_W :UAV_BURSTCOUNT_W - BURSTCOUNT_SHIFT_SELECTOR;localparam BYTEENABLE_ADDRESS_BITS = ( clog2_plusone(UAV_BYTEENABLE_W) - 1 ) >= 1 ? clog2_plusone(UAV_BYTEENABLE_W) - 1 : 1;// Calculate the symbols per word as the power of 2 extended symbols per wordwire [31 : 0] symbols_per_word_int = 2**(clog2_plusone(AV_SYMBOLS_PER_WORD[UAV_BURSTCOUNT_W : 0] - 1));wire [UAV_BURSTCOUNT_W-1 : 0] symbols_per_word = symbols_per_word_int[UAV_BURSTCOUNT_W-1 : 0];// +--------------------------------// |Backwards Compatibility Signals// +--------------------------------assign av_clken = (USE_UAV_CLKEN) ? uav_clken : 1'b1;assign av_debugaccess = uav_debugaccess;// +-------------------// |Passthru Signals// +-------------------reg [1 : 0] av_response_delayed;always @(posedge clk, posedge reset) beginif (reset) beginav_response_delayed <= 2'b0;end else beginav_response_delayed <= av_response;endendalways_combbeginif (!USE_READRESPONSE && !USE_WRITERESPONSE) beginuav_response = '0;end else beginif (AV_READLATENCY != 0 || USE_READDATAVALID) beginuav_response = av_response;end else beginuav_response = av_response_delayed;endendend// assign av_writeresponserequest = uav_writeresponserequest;assign uav_writeresponsevalid = av_writeresponsevalid;//-------------------------//Writedata and Byteenable//-------------------------always@* beginav_byteenable = '0;av_byteenable = uav_byteenable[AV_BYTEENABLE_W - 1 : 0];endalways@* beginav_writedata = '0;av_writedata = uav_writedata[AV_DATA_W - 1 : 0];end// +-------------------// |Calculated Signals// +-------------------logic [UAV_ADDRESS_W - 1 : 0 ] real_uav_address;function [BYTEENABLE_ADDRESS_BITS - 1 : 0 ] decode_byteenable;input [UAV_BYTEENABLE_W - 1 : 0 ] byteenable;for(int i = 0 ; i < UAV_BYTEENABLE_W; i++ ) beginif(byteenable[i] == 1) beginreturn i;endendreturn '0;endfunctionreg [AV_BURSTCOUNT_W - 1 : 0] burstcount_reg;reg [AV_ADDRESS_W - 1 : 0] address_reg;always@(posedge clk, posedge reset) beginif(reset) beginburstcount_reg <= '0;address_reg <= '0;end else beginburstcount_reg <= burstcount_reg;address_reg <= address_reg;if(av_beginbursttransfer) beginburstcount_reg <= uav_burstcount [ BURSTCOUNT_HIGH - 1 + BURSTCOUNT_SHIFT_SELECTOR : BURSTCOUNT_SHIFT_SELECTOR ];address_reg <= real_uav_address [ ADDRESS_HIGH - 1 + ADDRESS_SHIFT_SELECTOR : ADDRESS_SHIFT_SELECTOR ];endendendlogic [BYTEENABLE_ADDRESS_BITS-1:0] temp_wire;always@* beginif( AV_REQUIRE_UNALIGNED_ADDRESSES == 1) begintemp_wire = decode_byteenable(uav_byteenable);real_uav_address = { uav_address[UAV_ADDRESS_W - 1 : BYTEENABLE_ADDRESS_BITS ], temp_wire[BYTEENABLE_ADDRESS_BITS - 1 : 0 ] };end else beginreal_uav_address = uav_address;endav_address = real_uav_address[ADDRESS_HIGH - 1 + ADDRESS_SHIFT_SELECTOR : ADDRESS_SHIFT_SELECTOR ];if( AV_CONSTANT_BURST_BEHAVIOR && !UAV_CONSTANT_BURST_BEHAVIOR && ~av_beginbursttransfer )av_address = address_reg;endalways@* beginav_burstcount=uav_burstcount[BURSTCOUNT_HIGH - 1 + BURSTCOUNT_SHIFT_SELECTOR : BURSTCOUNT_SHIFT_SELECTOR ];if( AV_CONSTANT_BURST_BEHAVIOR && !UAV_CONSTANT_BURST_BEHAVIOR && ~av_beginbursttransfer )av_burstcount = burstcount_reg;endalways@* beginav_lock = uav_lock;end// -------------------// Writebyteenable Assignment// -------------------always@* beginav_writebyteenable = { (AV_BYTEENABLE_W){uav_write} } & uav_byteenable[AV_BYTEENABLE_W - 1 : 0];end// -------------------// Waitrequest Assignment// -------------------reg av_waitrequest_generated;reg av_waitrequest_generated_read;reg av_waitrequest_generated_write;reg waitrequest_reset_override;reg [ ( LOG2_OF_LATENCY_SUM ? LOG2_OF_LATENCY_SUM - 1 : 0 ) : 0 ] wait_latency_counter;always@(posedge reset, posedge clk) beginif(reset) beginwait_latency_counter <= '0;waitrequest_reset_override <= 1'h1;end else beginwaitrequest_reset_override <= 1'h0;wait_latency_counter <= '0;if( ~uav_waitrequest | waitrequest_reset_override )wait_latency_counter <= '0;else if( uav_read | uav_write )wait_latency_counter <= wait_latency_counter + 1'h1;endendalways @* beginav_read = uav_read;av_write = uav_write;av_waitrequest_generated = 1'h1;av_waitrequest_generated_read = 1'h1;av_waitrequest_generated_write = 1'h1;if(LOG2_OF_LATENCY_SUM == 1)av_waitrequest_generated = 0;if(LOG2_OF_LATENCY_SUM > 1 && !USE_WAITREQUEST) beginav_read = wait_latency_counter >= AV_SETUP_WAIT_CYCLES && uav_read;av_write = wait_latency_counter >= AV_SETUP_WAIT_CYCLES && uav_write && wait_latency_counter <= AV_WRITE_WAIT_INDEXED;av_waitrequest_generated_read = wait_latency_counter != AV_READ_WAIT_INDEXED;av_waitrequest_generated_write = wait_latency_counter != AV_DATA_HOLD_INDEXED;if(uav_write)av_waitrequest_generated = av_waitrequest_generated_write;elseav_waitrequest_generated = av_waitrequest_generated_read;endif(USE_WAITREQUEST) beginuav_waitrequest = av_waitrequest;end else beginuav_waitrequest = av_waitrequest_generated | waitrequest_reset_override;endend// --------------// Readdata Assignment// --------------reg[(AV_DATA_W ? AV_DATA_W -1 : 0 ): 0] av_readdata_pre;always@(posedge clk, posedge reset) beginif(reset)av_readdata_pre <= 'b0;elseav_readdata_pre <= av_readdata;endalways@* beginuav_readdata = {UAV_DATA_W{1'b0}};if( AV_READLATENCY != 0 || USE_READDATAVALID ) beginuav_readdata[AV_DATA_W-1:0] = av_readdata;end else beginuav_readdata[AV_DATA_W-1:0] = av_readdata_pre;endend// -------------------// Readdatavalid Assigment// -------------------reg[(AV_READLATENCY>0 ? AV_READLATENCY-1:0) :0] read_latency_shift_reg;reg top_read_latency_shift_reg;always@* beginuav_readdatavalid=top_read_latency_shift_reg;if(USE_READDATAVALID) beginuav_readdatavalid = av_readdatavalid;endendalways@* begintop_read_latency_shift_reg = uav_read & ~uav_waitrequest & ~waitrequest_reset_override;if(AV_READLATENCY == 1 || AV_READLATENCY == 0 ) begintop_read_latency_shift_reg=read_latency_shift_reg;endif (AV_READLATENCY > 1) begintop_read_latency_shift_reg = read_latency_shift_reg[(AV_READLATENCY ? AV_READLATENCY-1 : 0)];endendalways@(posedge reset, posedge clk) beginif (reset) beginread_latency_shift_reg <= '0;end else if (av_clken) beginread_latency_shift_reg[0] <= uav_read && ~uav_waitrequest & ~waitrequest_reset_override;for (int i=0; i+1 < AV_READLATENCY ; i+=1 ) beginread_latency_shift_reg[i+1] <= read_latency_shift_reg[i];endendend// ------------// Chipselect and OutputEnable// ------------reg av_chipselect_pre;wire cs_extension;reg av_outputenable_pre;assign av_chipselect = (uav_read | uav_write) ? 1'b1 : av_chipselect_pre;assign cs_extension = ( (^ read_latency_shift_reg) & ~top_read_latency_shift_reg ) | ((| read_latency_shift_reg) & ~(^ read_latency_shift_reg));assign av_outputenable = uav_read ? 1'b1 : av_outputenable_pre;always@(posedge reset, posedge clk) beginif(reset)av_outputenable_pre <= 1'b0;else if( AV_READLATENCY == 0 && AV_READ_WAIT_INDEXED != 0 )av_outputenable_pre <= 0;elseav_outputenable_pre <= cs_extension | uav_read;endalways@(posedge reset, posedge clk) beginif(reset) beginav_chipselect_pre <= 1'b0;end else beginav_chipselect_pre <= 1'b0;if(AV_READLATENCY != 0 && CHIPSELECT_THROUGH_READLATENCY == 1) begin//The AV_READLATENCY term is only here to prevent chipselect from remaining asserted while read and write fall.//There is no functional impact as 0 cycle transactions are treated as 1 cycle on the other side of the translator.if(uav_read) beginav_chipselect_pre <= 1'b1;end else if(cs_extension == 1) beginav_chipselect_pre <= 1'b1;endendendend// -------------------// Begintransfer Assigment// -------------------reg end_begintransfer;always@* beginav_begintransfer = ( uav_write | uav_read ) & ~end_begintransfer;endalways@ ( posedge clk or posedge reset ) beginif(reset) beginend_begintransfer <= 1'b0;end else beginif(av_begintransfer == 1 && uav_waitrequest && ~waitrequest_reset_override)end_begintransfer <= 1'b1;else if(uav_waitrequest)end_begintransfer <= end_begintransfer;elseend_begintransfer <= 1'b0;endend// -------------------// Beginbursttransfer Assigment// -------------------reg end_beginbursttransfer;reg in_transfer;always@* beginav_beginbursttransfer = uav_read ? av_begintransfer : (av_begintransfer && ~end_beginbursttransfer && ~in_transfer);endalways@ ( posedge clk or posedge reset ) beginif(reset) beginend_beginbursttransfer <= 1'b0;in_transfer <= 1'b0;end else beginend_beginbursttransfer <= uav_write & ( uav_burstcount != symbols_per_word );if(uav_write && uav_burstcount == symbols_per_word)in_transfer <=1'b0;else if(uav_write)in_transfer <=1'b1;endendendmodule
