URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/orpsocv2/boards/xilinx
- from Rev 563 to Rev 568
- ↔ Reverse comparison
Rev 563 → Rev 568
/s3adsp1800/bench/verilog/ddr2_model.v
0,0 → 1,2024
/**************************************************************************************** |
* |
* File Name: ddr2_model.v |
* Version: 5.80 |
* Model: BUS Functional |
* |
* Dependencies: ddr2_parameters.v |
* |
* Description: Micron SDRAM DDR2 (Double Data Rate 2) |
* |
* Limitation: - doesn't check for average refresh timings |
* - positive ck and ck_n edges are used to form internal clock |
* - positive dqs and dqs_n edges are used to latch data |
* - test mode is not modeled |
* |
* Note: - Set simulator resolution to "ps" accuracy |
* - Set Debug = 0 to disable $display messages |
* |
* Disclaimer This software code and all associated documentation, comments or other |
* of Warranty: information (collectively "Software") is provided "AS IS" without |
* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY |
* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED |
* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES |
* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT |
* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE |
* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE. |
* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR |
* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS, |
* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE |
* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI, |
* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT, |
* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING, |
* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION, |
* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE |
* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
* DAMAGES. Because some jurisdictions prohibit the exclusion or |
* limitation of liability for consequential or incidental damages, the |
* above limitation may not apply to you. |
* |
* Copyright 2003 Micron Technology, Inc. All rights reserved. |
* |
* Rev Author Date Changes |
* --------------------------------------------------------------------------------------- |
* 1.00 JMK 07/29/03 Initial Release |
* 1.10 JMK 08/09/03 Timing Parameter updates to tIS, tIH, tDS, tDH |
* 2.20 JMK 08/07/03 General cleanup |
* 2.30 JMK 11/26/03 Added CL_MIN, CL_MAX, wl_min and wl_max parameters. |
* Added AL_MIN and AL_MAX parameters. |
* Removed support for OCD. |
* 2.40 JMK 01/15/04 Removed verilog 2001 constructs. |
* 2.50 JMK 01/29/04 Removed tRP checks during Precharge command. |
* 2.60 JMK 04/20/04 Fixed tWTR check. |
* 2.70 JMK 04/30/04 Added tRFC maximum check. |
* Combined Self Refresh and Power Down always blocks. |
* Added Reset Function (CKE LOW Anytime). |
* 2.80 JMK 08/19/04 Precharge is treated as NOP when bank is not active. |
* Added checks for tRAS, tWR, tRTP to any bank during Pre-All. |
* tRFC maximum violation will only display one time. |
* 2.90 JMK 11/05/04 Fixed DQS checking during write. |
* Fixed false tRFC max assertion during power up and self ref. |
* Added warning for 200us CKE low time during initialization. |
* Added -3, -3E, and -37V speed grades to ddr2_parameters.v |
* 3.00 JMK 04/22/05 Removed ODT off requirement during power down. |
* Added tAOND, tAOFD, tANPD, tAXPD, tAONPD, and tAOFPD parameters. |
* Added ODT status messages. |
* Updated the initialization sequence. |
* Disable ODT and CLK pins during self refresh. |
* Disable cmd and addr pins during power down and self refresh. |
* 3.10 JMK 06/07/05 Disable trpa checking if the part does not have 8 banks. |
* Changed tAXPD message from error to a warning. |
* Added tDSS checking. |
* Removed tDQSL checking during tWPRE and tWPST. |
* Fixed a burst order error during writes. |
* Renamed parameters file with .vh extension. |
* 3.20 JMK 07/18/05 Removed 14 tCK requirement from LMR to READ. |
* 3.30 JMK 08/03/05 Added check for interrupting a burst with auto precharge. |
* 4.00 JMK 11/21/05 Parameter names all UPPERCASE, signal names all lowercase. |
* Clock jitter can be tolerated within specification range. |
* Clock frequency is sampled from the CK pin. |
* Scaleable up to 64 DQ and 16 DQS bits. |
* Read data can be randomly skewed using RANDOM_OUT_DELAY. |
* Parameterized read and write DQS, and read DQ. |
* Initialization can be bypassed using initialize task. |
* 4.10 JMK 11/30/05 Fixed compile errors when `MAX_MEM was defined. |
* 4.20 JMK 12/09/05 Fixed memory addressing error when `MAX_MEM was defined. |
* 4.30 JMK 02/15/06 Added dummy write to initialization sequence. |
* Removed tWPST maximum checking. |
* Rising dqs_n edge latches data when enabled in EMR. |
* Fixed a sign error in the tJIT(cc) calculation. |
* 4.40 JMK 02/16/06 Fixed dummy write when`MAX_MEM was defined. |
* 4.50 JMK 02/27/06 Fixed extra tDQSS assertions. |
* Fixed tRCD and tWTR checking. |
* Errors entering Power Down or Self Refresh will cause reset. |
* Ignore dqs_n when disabled in EMR. |
* 5.00 JMK 04/24/06 Test stimulus now included from external file (subtest.vh) |
* Fixed tRFC max assertion during self refresh. |
* Fixed tANPD checking during Power Down. |
* Removed dummy write from initialization sequence. |
* 5.01 JMK 04/28/06 Fixed Auto Precharge to Load Mode, Refresh and Self Refresh. |
* Removed Auto Precharge error message during Power Down Enter. |
* 5.10 JMK 07/26/06 Created internal clock using ck and ck_n. |
* RDQS can only be enabled in EMR for x8 configurations. |
* CAS latency is checked vs frequency when DLL locks. |
* tMOD changed from tCK units to ns units. |
* Added 50 Ohm setting for Rtt in EMR. |
* Improved checking of DQS during writes. |
* 5.20 JMK 10/02/06 Fixed DQS checking for interrupting write to write and x16. |
* 5.30 JMK 05/25/07 Fixed checking for 0-Z transition on write postamble. |
* 5.50 JMK 05/30/08 Renamed ddr2_dimm.v to ddr2_module.v and added SODIMM support. |
* Added a register delay to ddr2_module.v when RDIMM is defined. |
* Added multi-chip package model support in ddr2_mcp.v |
* Added High Temp Self Refresh rate setting in EMRS2[7] |
* 5.70 JMK 04/23/09 Updated tRPA definition |
* Increased internal width to 72 bit DQ bus |
* 5.80 SPH 08/12/09 Fixed tRAS maximum violation (only check if bank still open) |
****************************************************************************************/ |
|
// DO NOT CHANGE THE TIMESCALE |
// MAKE SURE YOUR SIMULATOR USES "PS" RESOLUTION |
`timescale 1ps / 1ps |
|
module ddr2_model ( |
ck, |
ck_n, |
cke, |
cs_n, |
ras_n, |
cas_n, |
we_n, |
dm_rdqs, |
ba, |
addr, |
dq, |
dqs, |
dqs_n, |
rdqs_n, |
odt |
); |
|
`include "ddr2_model_parameters.v" |
|
// text macros |
`define DQ_PER_DQS DQ_BITS/DQS_BITS |
`define BANKS (1<<BA_BITS) |
`define MAX_BITS (BA_BITS+ROW_BITS+COL_BITS-BL_BITS) |
`define MAX_SIZE (1<<(BA_BITS+ROW_BITS+COL_BITS-BL_BITS)) |
`define MEM_SIZE (1<<MEM_BITS) |
`define MAX_PIPE 2*(AL_MAX + CL_MAX) |
|
// Declare Ports |
input ck; |
input ck_n; |
input cke; |
input cs_n; |
input ras_n; |
input cas_n; |
input we_n; |
inout [DM_BITS-1:0] dm_rdqs; |
input [BA_BITS-1:0] ba; |
input [ADDR_BITS-1:0] addr; |
inout [DQ_BITS-1:0] dq; |
inout [DQS_BITS-1:0] dqs; |
inout [DQS_BITS-1:0] dqs_n; |
output [DQS_BITS-1:0] rdqs_n; |
input odt; |
|
// clock jitter |
real tck_avg; |
time tck_sample [TDLLK-1:0]; |
time tch_sample [TDLLK-1:0]; |
time tcl_sample [TDLLK-1:0]; |
time tck_i; |
time tch_i; |
time tcl_i; |
real tch_avg; |
real tcl_avg; |
time tm_ck_pos; |
time tm_ck_neg; |
real tjit_per_rtime; |
integer tjit_cc_time; |
real terr_nper_rtime; |
|
// clock skew |
real out_delay; |
integer dqsck [DQS_BITS-1:0]; |
integer dqsck_min; |
integer dqsck_max; |
integer dqsq_min; |
integer dqsq_max; |
integer seed; |
|
// Mode Registers |
reg burst_order; |
reg [BL_BITS:0] burst_length; |
integer cas_latency; |
integer additive_latency; |
reg dll_reset; |
reg dll_locked; |
reg dll_en; |
integer write_recovery; |
reg low_power; |
reg [1:0] odt_rtt; |
reg odt_en; |
reg [2:0] ocd; |
reg dqs_n_en; |
reg rdqs_en; |
reg out_en; |
integer read_latency; |
integer write_latency; |
|
// cmd encoding |
parameter LOAD_MODE = 4'b0000; |
parameter REFRESH = 4'b0001; |
parameter PRECHARGE = 4'b0010; |
parameter ACTIVATE = 4'b0011; |
parameter WRITE = 4'b0100; |
parameter READ = 4'b0101; |
parameter NOP = 4'b0111; |
parameter PWR_DOWN = 4'b1000; |
parameter SELF_REF = 4'b100; |
|
|
reg [8*9-1:0] cmd_string [9:0]; |
initial begin |
cmd_string[LOAD_MODE] = "Load Mode"; |
cmd_string[REFRESH ] = "Refresh "; |
cmd_string[PRECHARGE] = "Precharge"; |
cmd_string[ACTIVATE ] = "Activate "; |
cmd_string[WRITE ] = "Write "; |
cmd_string[READ ] = "Read "; |
cmd_string[NOP ] = "No Op "; |
cmd_string[PWR_DOWN ] = "Pwr Down "; |
cmd_string[SELF_REF ] = "Self Ref "; |
end |
|
// command state |
reg [`BANKS-1:0] active_bank; |
reg [`BANKS-1:0] auto_precharge_bank; |
reg [`BANKS-1:0] write_precharge_bank; |
reg [`BANKS-1:0] read_precharge_bank; |
reg [ROW_BITS-1:0] active_row [`BANKS-1:0]; |
reg in_power_down; |
reg in_self_refresh; |
reg [3:0] init_mode_reg; |
reg init_done; |
integer init_step; |
reg er_trfc_max; |
reg odt_state; |
reg prev_odt; |
|
// cmd timers/counters |
integer ref_cntr; |
integer ck_cntr; |
integer ck_load_mode; |
integer ck_write; |
integer ck_read; |
integer ck_write_ap; |
integer ck_power_down; |
integer ck_slow_exit_pd; |
integer ck_self_refresh; |
integer ck_cke; |
integer ck_odt; |
integer ck_dll_reset; |
integer ck_bank_write [`BANKS-1:0]; |
integer ck_bank_read [`BANKS-1:0]; |
time tm_refresh; |
time tm_precharge; |
time tm_precharge_all; |
time tm_activate; |
time tm_write_end; |
time tm_self_refresh; |
time tm_odt_en; |
time tm_bank_precharge [`BANKS-1:0]; |
time tm_bank_activate [`BANKS-1:0]; |
time tm_bank_write_end [`BANKS-1:0]; |
time tm_bank_read_end [`BANKS-1:0]; |
|
// pipelines |
reg [`MAX_PIPE:0] al_pipeline; |
reg [`MAX_PIPE:0] wr_pipeline; |
reg [`MAX_PIPE:0] rd_pipeline; |
reg [`MAX_PIPE:0] odt_pipeline; |
reg [BA_BITS-1:0] ba_pipeline [`MAX_PIPE:0]; |
reg [ROW_BITS-1:0] row_pipeline [`MAX_PIPE:0]; |
reg [COL_BITS-1:0] col_pipeline [`MAX_PIPE:0]; |
reg prev_cke; |
|
// data state |
reg [BL_MAX*DQ_BITS-1:0] memory_data; |
reg [BL_MAX*DQ_BITS-1:0] bit_mask; |
reg [BL_BITS-1:0] burst_position; |
reg [BL_BITS:0] burst_cntr; |
reg [DQ_BITS-1:0] dq_temp; |
reg [35:0] check_write_postamble; |
reg [35:0] check_write_preamble; |
reg [35:0] check_write_dqs_high; |
reg [35:0] check_write_dqs_low; |
reg [17:0] check_dm_tdipw; |
reg [71:0] check_dq_tdipw; |
|
// data timers/counters |
time tm_cke; |
time tm_odt; |
time tm_tdqss; |
time tm_dm [17:0]; |
time tm_dqs [17:0]; |
time tm_dqs_pos [35:0]; |
time tm_dqss_pos [35:0]; |
time tm_dqs_neg [35:0]; |
time tm_dq [71:0]; |
time tm_cmd_addr [22:0]; |
reg [8*7-1:0] cmd_addr_string [22:0]; |
initial begin |
cmd_addr_string[ 0] = "CS_N "; |
cmd_addr_string[ 1] = "RAS_N "; |
cmd_addr_string[ 2] = "CAS_N "; |
cmd_addr_string[ 3] = "WE_N "; |
cmd_addr_string[ 4] = "BA 0 "; |
cmd_addr_string[ 5] = "BA 1 "; |
cmd_addr_string[ 6] = "BA 2 "; |
cmd_addr_string[ 7] = "ADDR 0"; |
cmd_addr_string[ 8] = "ADDR 1"; |
cmd_addr_string[ 9] = "ADDR 2"; |
cmd_addr_string[10] = "ADDR 3"; |
cmd_addr_string[11] = "ADDR 4"; |
cmd_addr_string[12] = "ADDR 5"; |
cmd_addr_string[13] = "ADDR 6"; |
cmd_addr_string[14] = "ADDR 7"; |
cmd_addr_string[15] = "ADDR 8"; |
cmd_addr_string[16] = "ADDR 9"; |
cmd_addr_string[17] = "ADDR 10"; |
cmd_addr_string[18] = "ADDR 11"; |
cmd_addr_string[19] = "ADDR 12"; |
cmd_addr_string[20] = "ADDR 13"; |
cmd_addr_string[21] = "ADDR 14"; |
cmd_addr_string[22] = "ADDR 15"; |
end |
|
reg [8*5-1:0] dqs_string [1:0]; |
initial begin |
dqs_string[0] = "DQS "; |
dqs_string[1] = "DQS_N"; |
end |
|
// Memory Storage |
`ifdef MAX_MEM |
reg [BL_MAX*DQ_BITS-1:0] memory [0:`MAX_SIZE-1]; |
`else |
reg [BL_MAX*DQ_BITS-1:0] memory [0:`MEM_SIZE-1]; |
reg [`MAX_BITS-1:0] address [0:`MEM_SIZE-1]; |
reg [MEM_BITS:0] memory_index; |
reg [MEM_BITS:0] memory_used; |
`endif |
|
// receive |
reg ck_in; |
reg ck_n_in; |
reg cke_in; |
reg cs_n_in; |
reg ras_n_in; |
reg cas_n_in; |
reg we_n_in; |
reg [17:0] dm_in; |
reg [2:0] ba_in; |
reg [15:0] addr_in; |
reg [71:0] dq_in; |
reg [35:0] dqs_in; |
reg odt_in; |
|
reg [17:0] dm_in_pos; |
reg [17:0] dm_in_neg; |
reg [71:0] dq_in_pos; |
reg [71:0] dq_in_neg; |
reg dq_in_valid; |
reg dqs_in_valid; |
integer wdqs_cntr; |
integer wdq_cntr; |
integer wdqs_pos_cntr [35:0]; |
reg b2b_write; |
reg [35:0] prev_dqs_in; |
reg diff_ck; |
|
always @(ck ) ck_in <= #BUS_DELAY ck; |
always @(ck_n ) ck_n_in <= #BUS_DELAY ck_n; |
always @(cke ) cke_in <= #BUS_DELAY cke; |
always @(cs_n ) cs_n_in <= #BUS_DELAY cs_n; |
always @(ras_n ) ras_n_in <= #BUS_DELAY ras_n; |
always @(cas_n ) cas_n_in <= #BUS_DELAY cas_n; |
always @(we_n ) we_n_in <= #BUS_DELAY we_n; |
always @(dm_rdqs) dm_in <= #BUS_DELAY dm_rdqs; |
always @(ba ) ba_in <= #BUS_DELAY ba; |
always @(addr ) addr_in <= #BUS_DELAY addr; |
always @(dq ) dq_in <= #BUS_DELAY dq; |
always @(dqs or dqs_n) dqs_in <= #BUS_DELAY (dqs_n<<18) | dqs; |
always @(odt ) odt_in <= #BUS_DELAY odt; |
// create internal clock |
always @(posedge ck_in) diff_ck <= ck_in; |
always @(posedge ck_n_in) diff_ck <= ~ck_n_in; |
|
wire [17:0] dqs_even = dqs_in[17:0]; |
wire [17:0] dqs_odd = dqs_n_en ? dqs_in[35:18] : ~dqs_in[17:0]; |
wire [3:0] cmd_n_in = !cs_n_in ? {ras_n_in, cas_n_in, we_n_in} : NOP; //deselect = nop |
|
// transmit |
reg dqs_out_en; |
reg [DQS_BITS-1:0] dqs_out_en_dly; |
reg dqs_out; |
reg [DQS_BITS-1:0] dqs_out_dly; |
reg dq_out_en; |
reg [DQ_BITS-1:0] dq_out_en_dly; |
reg [DQ_BITS-1:0] dq_out; |
reg [DQ_BITS-1:0] dq_out_dly; |
integer rdqsen_cntr; |
integer rdqs_cntr; |
integer rdqen_cntr; |
integer rdq_cntr; |
|
bufif1 buf_dqs [DQS_BITS-1:0] (dqs, dqs_out_dly, dqs_out_en_dly & {DQS_BITS{out_en}}); |
bufif1 buf_dm [DM_BITS-1:0] (dm_rdqs, dqs_out_dly, dqs_out_en_dly & {DM_BITS {out_en}} & {DM_BITS{rdqs_en}}); |
bufif1 buf_dqs_n [DQS_BITS-1:0] (dqs_n, ~dqs_out_dly, dqs_out_en_dly & {DQS_BITS{out_en}} & {DQS_BITS{dqs_n_en}}); |
bufif1 buf_rdqs_n [DQS_BITS-1:0] (rdqs_n, ~dqs_out_dly, dqs_out_en_dly & {DQS_BITS{out_en}} & {DQS_BITS{dqs_n_en}} & {DQS_BITS{rdqs_en}}); |
bufif1 buf_dq [DQ_BITS-1:0] (dq, dq_out_dly, dq_out_en_dly & {DQ_BITS {out_en}}); |
|
initial begin |
if (BL_MAX < 2) |
$display("%m ERROR: BL_MAX parameter must be >= 2. \nBL_MAX = %d", BL_MAX); |
if ((1<<BO_BITS) > BL_MAX) |
$display("%m ERROR: 2^BO_BITS cannot be greater than BL_MAX parameter."); |
$timeformat (-12, 1, " ps", 1); |
reset_task; |
seed = RANDOM_SEED; |
ck_cntr = 0; |
end |
|
// calculate the absolute value of a real number |
function real abs_value; |
input arg; |
real arg; |
begin |
if (arg < 0.0) |
abs_value = -1.0 * arg; |
else |
abs_value = arg; |
end |
endfunction |
|
`ifdef MAX_MEM |
`else |
function get_index; |
input [`MAX_BITS-1:0] addr; |
begin : index |
get_index = 0; |
for (memory_index=0; memory_index<memory_used; memory_index=memory_index+1) begin |
if (address[memory_index] == addr) begin |
get_index = 1; |
disable index; |
end |
end |
end |
endfunction |
`endif |
|
task memory_write; |
input [BA_BITS-1:0] bank; |
input [ROW_BITS-1:0] row; |
input [COL_BITS-1:0] col; |
input [BL_MAX*DQ_BITS-1:0] data; |
reg [`MAX_BITS-1:0] addr; |
begin |
// chop off the lowest address bits |
addr = {bank, row, col}/BL_MAX; |
`ifdef MAX_MEM |
memory[addr] = data; |
`else |
if (get_index(addr)) begin |
address[memory_index] = addr; |
memory[memory_index] = data; |
end else if (memory_used == `MEM_SIZE) begin |
$display ("%m: at time %t ERROR: Memory overflow. Write to Address %h with Data %h will be lost.\nYou must increase the MEM_BITS parameter or define MAX_MEM.", $time, addr, data); |
if (STOP_ON_ERROR) $stop(0); |
end else begin |
address[memory_used] = addr; |
memory[memory_used] = data; |
memory_used = memory_used + 1; |
end |
`endif |
end |
endtask |
|
task memory_read; |
input [BA_BITS-1:0] bank; |
input [ROW_BITS-1:0] row; |
input [COL_BITS-1:0] col; |
output [BL_MAX*DQ_BITS-1:0] data; |
reg [`MAX_BITS-1:0] addr; |
begin |
// chop off the lowest address bits |
addr = {bank, row, col}/BL_MAX; |
`ifdef MAX_MEM |
data = memory[addr]; |
`else |
if (get_index(addr)) begin |
data = memory[memory_index]; |
end else begin |
data = {BL_MAX*DQ_BITS{1'bx}}; |
end |
`endif |
end |
endtask |
|
// Before this task runs, the model must be in a valid state for precharge power down. |
// After this task runs, NOP commands must be issued until tRFC has been met |
task initialize; |
input [ADDR_BITS-1:0] mode_reg0; |
input [ADDR_BITS-1:0] mode_reg1; |
input [ADDR_BITS-1:0] mode_reg2; |
input [ADDR_BITS-1:0] mode_reg3; |
begin |
if (DEBUG) $display ("%m: at time %t INFO: Performing Initialization Sequence", $time); |
cmd_task(1, NOP, 'bx, 'bx); |
cmd_task(1, PRECHARGE, 'bx, 1<<AP); // Precharege ALL |
cmd_task(1, LOAD_MODE, 3, mode_reg3); |
cmd_task(1, LOAD_MODE, 2, mode_reg2); |
cmd_task(1, LOAD_MODE, 1, mode_reg1); |
cmd_task(1, LOAD_MODE, 0, mode_reg0 | 'h100); // DLL Reset |
cmd_task(1, PRECHARGE, 'bx, 1<<AP); // Precharege ALL |
cmd_task(1, REFRESH, 'bx, 'bx); |
cmd_task(1, REFRESH, 'bx, 'bx); |
cmd_task(1, LOAD_MODE, 0, mode_reg0); |
cmd_task(1, LOAD_MODE, 1, mode_reg1 | 'h380); // OCD Default |
cmd_task(1, LOAD_MODE, 1, mode_reg1); |
cmd_task(0, NOP, 'bx, 'bx); |
end |
endtask |
|
task reset_task; |
integer i; |
begin |
// disable inputs |
dq_in_valid = 0; |
dqs_in_valid <= 0; |
wdqs_cntr = 0; |
wdq_cntr = 0; |
for (i=0; i<36; i=i+1) begin |
wdqs_pos_cntr[i] <= 0; |
end |
b2b_write <= 0; |
// disable outputs |
out_en = 0; |
dqs_n_en = 0; |
rdqs_en = 0; |
dq_out_en = 0; |
rdq_cntr = 0; |
dqs_out_en = 0; |
rdqs_cntr = 0; |
// disable ODT |
odt_en = 0; |
odt_state = 0; |
// reset bank state |
active_bank = {`BANKS{1'b1}}; |
auto_precharge_bank = 0; |
read_precharge_bank = 0; |
write_precharge_bank = 0; |
// require initialization sequence |
init_done = 0; |
init_step = 0; |
init_mode_reg = 0; |
// reset DLL |
dll_en = 0; |
dll_reset = 0; |
dll_locked = 0; |
ocd = 0; |
// exit power down and self refresh |
in_power_down = 0; |
in_self_refresh = 0; |
// clear pipelines |
al_pipeline = 0; |
wr_pipeline = 0; |
rd_pipeline = 0; |
odt_pipeline = 0; |
// clear memory |
`ifdef MAX_MEM |
for (i=0; i<=`MAX_SIZE; i=i+1) begin //erase memory ... one address at a time |
memory[i] <= 'bx; |
end |
`else |
memory_used <= 0; //erase memory |
`endif |
// clear maximum timing checks |
tm_refresh <= 'bx; |
for (i=0; i<`BANKS; i=i+1) begin |
tm_bank_activate[i] <= 'bx; |
end |
end |
endtask |
|
task chk_err; |
input samebank; |
input [BA_BITS-1:0] bank; |
input [3:0] fromcmd; |
input [3:0] cmd; |
reg err; |
begin |
// all matching case expressions will be evaluated |
casex ({samebank, fromcmd, cmd}) |
{1'b0, LOAD_MODE, 4'b0xxx } : begin if (ck_cntr - ck_load_mode < TMRD) $display ("%m: at time %t ERROR: tMRD violation during %s", $time, cmd_string[cmd]); end |
{1'b0, LOAD_MODE, 4'b100x } : begin if (ck_cntr - ck_load_mode < TMRD) begin $display ("%m: at time %t INFO: Load Mode to Reset condition.", $time); init_done = 0; end end |
{1'b0, REFRESH , 4'b0xxx } : begin if ($time - tm_refresh < TRFC_MIN) $display ("%m: at time %t ERROR: tRFC violation during %s", $time, cmd_string[cmd]); end |
{1'b0, REFRESH , PWR_DOWN } : ; // 1 tCK |
{1'b0, REFRESH , SELF_REF } : begin if ($time - tm_refresh < TRFC_MIN) begin $display ("%m: at time %t INFO: Refresh to Reset condition", $time); init_done = 0; end end |
{1'b0, PRECHARGE, 4'b000x } : begin if ($time - tm_precharge_all < TRPA) $display ("%m: at time %t ERROR: tRPA violation during %s", $time, cmd_string[cmd]); |
if ($time - tm_precharge < TRP) $display ("%m: at time %t ERROR: tRP violation during %s", $time, cmd_string[cmd]); end |
{1'b1, PRECHARGE, PRECHARGE} : begin if (DEBUG && ($time - tm_precharge_all < TRPA)) $display ("%m: at time %t INFO: Precharge All interruption during %s", $time, cmd_string[cmd]); |
if (DEBUG && ($time - tm_bank_precharge[bank] < TRP)) $display ("%m: at time %t INFO: Precharge bank %d interruption during %s", $time, cmd_string[cmd], bank); end |
{1'b1, PRECHARGE, ACTIVATE } : begin if ($time - tm_precharge_all < TRPA) $display ("%m: at time %t ERROR: tRPA violation during %s", $time, cmd_string[cmd]); |
if ($time - tm_bank_precharge[bank] < TRP) $display ("%m: at time %t ERROR: tRP violation during %s to bank %d", $time, cmd_string[cmd], bank); end |
{1'b0, PRECHARGE, PWR_DOWN } : ; //1 tCK, can be concurrent with auto precharge |
{1'b0, PRECHARGE, SELF_REF } : begin if (($time - tm_precharge_all < TRPA) || ($time - tm_precharge < TRP)) begin $display ("%m: at time %t INFO: Precharge to Reset condition", $time); init_done = 0; end end |
{1'b0, ACTIVATE , REFRESH } : begin if ($time - tm_activate < TRC) $display ("%m: at time %t ERROR: tRC violation during %s", $time, cmd_string[cmd]); end |
{1'b1, ACTIVATE , PRECHARGE} : begin if (($time - tm_bank_activate[bank] > TRAS_MAX) && (active_bank[bank] === 1'b1)) $display ("%m: at time %t ERROR: tRAS maximum violation during %s to bank %d", $time, cmd_string[cmd], bank); |
if ($time - tm_bank_activate[bank] < TRAS_MIN) $display ("%m: at time %t ERROR: tRAS minimum violation during %s to bank %d", $time, cmd_string[cmd], bank);end |
{1'b0, ACTIVATE , ACTIVATE } : begin if ($time - tm_activate < TRRD) $display ("%m: at time %t ERROR: tRRD violation during %s to bank %d", $time, cmd_string[cmd], bank); end |
{1'b1, ACTIVATE , ACTIVATE } : begin if ($time - tm_bank_activate[bank] < TRC) $display ("%m: at time %t ERROR: tRC violation during %s to bank %d", $time, cmd_string[cmd], bank); end |
{1'b1, ACTIVATE , 4'b010x } : ; // tRCD is checked outside this task |
{1'b1, ACTIVATE , PWR_DOWN } : ; // 1 tCK |
{1'b1, WRITE , PRECHARGE} : begin if ((ck_cntr - ck_bank_write[bank] <= write_latency + burst_length/2) || ($time - tm_bank_write_end[bank] < TWR)) $display ("%m: at time %t ERROR: tWR violation during %s to bank %d", $time, cmd_string[cmd], bank); end |
{1'b0, WRITE , WRITE } : begin if (ck_cntr - ck_write < TCCD) $display ("%m: at time %t ERROR: tCCD violation during %s to bank %d", $time, cmd_string[cmd], bank); end |
{1'b0, WRITE , READ } : begin if ((ck_load_mode < ck_write) && (ck_cntr - ck_write < write_latency + burst_length/2 + 2 - additive_latency)) $display ("%m: at time %t ERROR: tWTR violation during %s to bank %d", $time, cmd_string[cmd], bank); end |
{1'b0, WRITE , PWR_DOWN } : begin if ((ck_load_mode < ck_write) && ( |
|write_precharge_bank |
|| (ck_cntr - ck_write_ap < 1) |
|| (ck_cntr - ck_write < write_latency + burst_length/2 + 2) |
|| ($time - tm_write_end < TWTR))) begin $display ("%m: at time %t INFO: Write to Reset condition", $time); init_done = 0; end end |
{1'b1, READ , PRECHARGE} : begin if ((ck_cntr - ck_bank_read[bank] < additive_latency + burst_length/2) || ($time - tm_bank_read_end[bank] < TRTP)) $display ("%m: at time %t ERROR: tRTP violation during %s to bank %d", $time, cmd_string[cmd], bank); end |
{1'b0, READ , WRITE } : begin if ((ck_load_mode < ck_read) && (ck_cntr - ck_read < read_latency + burst_length/2 + 1 - write_latency)) $display ("%m: at time %t ERROR: tRTW violation during %s to bank %d", $time, cmd_string[cmd], bank); end |
{1'b0, READ , READ } : begin if (ck_cntr - ck_read < TCCD) $display ("%m: at time %t ERROR: tCCD violation during %s to bank %d", $time, cmd_string[cmd], bank); end |
{1'b0, READ , PWR_DOWN } : begin if ((ck_load_mode < ck_read) && (ck_cntr - ck_read < read_latency + burst_length/2 + 1)) begin $display ("%m: at time %t INFO: Read to Reset condition", $time); init_done = 0; end end |
{1'b0, PWR_DOWN , 4'b00xx } : begin if (ck_cntr - ck_power_down < TXP) $display ("%m: at time %t ERROR: tXP violation during %s", $time, cmd_string[cmd]); end |
{1'b0, PWR_DOWN , WRITE } : begin if (ck_cntr - ck_power_down < TXP) $display ("%m: at time %t ERROR: tXP violation during %s", $time, cmd_string[cmd]); end |
{1'b0, PWR_DOWN , READ } : begin if (ck_cntr - ck_slow_exit_pd < TXARDS - additive_latency) $display ("%m: at time %t ERROR: tXARDS violation during %s", $time, cmd_string[cmd]); |
else if (ck_cntr - ck_power_down < TXARD) $display ("%m: at time %t ERROR: tXARD violation during %s", $time, cmd_string[cmd]); end |
{1'b0, SELF_REF , 4'b00xx } : begin if ($time - tm_self_refresh < TXSNR) $display ("%m: at time %t ERROR: tXSNR violation during %s", $time, cmd_string[cmd]); end |
{1'b0, SELF_REF , WRITE } : begin if ($time - tm_self_refresh < TXSNR) $display ("%m: at time %t ERROR: tXSNR violation during %s", $time, cmd_string[cmd]); end |
{1'b0, SELF_REF , READ } : begin if (ck_cntr - ck_self_refresh < TXSRD) $display ("%m: at time %t ERROR: tXSRD violation during %s", $time, cmd_string[cmd]); end |
{1'b0, 4'b100x , 4'b100x } : begin if (ck_cntr - ck_cke < TCKE) begin $display ("%m: at time %t ERROR: tCKE violation on CKE", $time); init_done = 0; end end |
endcase |
end |
endtask |
|
task cmd_task; |
input cke; |
input [2:0] cmd; |
input [BA_BITS-1:0] bank; |
input [ADDR_BITS-1:0] addr; |
reg [`BANKS:0] i; |
integer j; |
reg [`BANKS:0] tfaw_cntr; |
reg [COL_BITS-1:0] col; |
begin |
|
// tRFC max check |
if (!er_trfc_max && !in_self_refresh) begin |
if ($time - tm_refresh > TRFC_MAX) begin |
$display ("%m: at time %t ERROR: tRFC maximum violation during %s", $time, cmd_string[cmd]); |
er_trfc_max = 1; |
end |
end |
if (cke) begin |
if ((cmd < NOP) && ((cmd != PRECHARGE) || !addr[AP])) begin |
for (j=0; j<NOP; j=j+1) begin |
chk_err(1'b0, bank, j, cmd); |
chk_err(1'b1, bank, j, cmd); |
end |
chk_err(1'b0, bank, PWR_DOWN, cmd); |
chk_err(1'b0, bank, SELF_REF, cmd); |
end |
|
case (cmd) |
LOAD_MODE : begin |
if (|active_bank) begin |
$display ("%m: at time %t ERROR: %s Failure. All banks must be Precharged.", $time, cmd_string[cmd]); |
if (STOP_ON_ERROR) $stop(0); |
end else begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d", $time, cmd_string[cmd], bank); |
case (bank) |
0 : begin |
// Burst Length |
burst_length = 1<<addr[2:0]; |
if ((burst_length >= BL_MIN) && (burst_length <= BL_MAX)) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d Burst Length = %d", $time, cmd_string[cmd], bank, burst_length); |
end else begin |
$display ("%m: at time %t ERROR: %s %d Illegal Burst Length = %d", $time, cmd_string[cmd], bank, burst_length); |
end |
// Burst Order |
burst_order = addr[3]; |
if (!burst_order) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d Burst Order = Sequential", $time, cmd_string[cmd], bank); |
end else if (burst_order) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d Burst Order = Interleaved", $time, cmd_string[cmd], bank); |
end else begin |
$display ("%m: at time %t ERROR: %s %d Illegal Burst Order = %d", $time, cmd_string[cmd], bank, burst_order); |
end |
// CAS Latency |
cas_latency = addr[6:4]; |
read_latency = cas_latency + additive_latency; |
write_latency = read_latency - 1; |
if ((cas_latency >= CL_MIN) && (cas_latency <= CL_MAX)) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d CAS Latency = %d", $time, cmd_string[cmd], bank, cas_latency); |
end else begin |
$display ("%m: at time %t ERROR: %s %d Illegal CAS Latency = %d", $time, cmd_string[cmd], bank, cas_latency); |
end |
// Test Mode |
if (!addr[7]) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d Test Mode = Normal", $time, cmd_string[cmd], bank); |
end else begin |
$display ("%m: at time %t ERROR: %s %d Illegal Test Mode = %d", $time, cmd_string[cmd], bank, addr[7]); |
end |
// DLL Reset |
dll_reset = addr[8]; |
if (!dll_reset) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d DLL Reset = Normal", $time, cmd_string[cmd], bank); |
end else if (dll_reset) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d DLL Reset = Reset DLL", $time, cmd_string[cmd], bank); |
dll_locked = 0; |
ck_dll_reset <= ck_cntr; |
end else begin |
$display ("%m: at time %t ERROR: %s %d Illegal DLL Reset = %d", $time, cmd_string[cmd], bank, dll_reset); |
end |
// Write Recovery |
write_recovery = addr[11:9] + 1; |
if ((write_recovery >= WR_MIN) && (write_recovery <= WR_MAX)) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d Write Recovery = %d", $time, cmd_string[cmd], bank, write_recovery); |
end else begin |
$display ("%m: at time %t ERROR: %s %d Illegal Write Recovery = %d", $time, cmd_string[cmd], bank, write_recovery); |
end |
// Power Down Mode |
low_power = addr[12]; |
if (!low_power) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d Power Down Mode = Fast Exit", $time, cmd_string[cmd], bank); |
end else if (low_power) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d Power Down Mode = Slow Exit", $time, cmd_string[cmd], bank); |
end else begin |
$display ("%m: at time %t ERROR: %s %d Illegal Power Down Mode = %d", $time, cmd_string[cmd], bank, low_power); |
end |
end |
1 : begin |
// DLL Enable |
dll_en = !addr[0]; |
if (!dll_en) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d DLL Enable = Disabled", $time, cmd_string[cmd], bank); |
end else if (dll_en) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d DLL Enable = Enabled", $time, cmd_string[cmd], bank); |
end else begin |
$display ("%m: at time %t ERROR: %s %d Illegal DLL Enable = %d", $time, cmd_string[cmd], bank, dll_en); |
end |
// Output Drive Strength |
if (!addr[1]) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d Output Drive Strength = Full", $time, cmd_string[cmd], bank); |
end else if (addr[1]) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d Output Drive Strength = Reduced", $time, cmd_string[cmd], bank); |
end else begin |
$display ("%m: at time %t ERROR: %s %d Illegal Output Drive Strength = %d", $time, cmd_string[cmd], bank, addr[1]); |
end |
// ODT Rtt |
odt_rtt = {addr[6], addr[2]}; |
if (odt_rtt == 2'b00) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d ODT Rtt = Disabled", $time, cmd_string[cmd], bank); |
odt_en = 0; |
end else if (odt_rtt == 2'b01) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d ODT Rtt = 75 Ohm", $time, cmd_string[cmd], bank); |
odt_en = 1; |
tm_odt_en <= $time; |
end else if (odt_rtt == 2'b10) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d ODT Rtt = 150 Ohm", $time, cmd_string[cmd], bank); |
odt_en = 1; |
tm_odt_en <= $time; |
end else if (odt_rtt == 2'b11) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d ODT Rtt = 50 Ohm", $time, cmd_string[cmd], bank); |
odt_en = 1; |
tm_odt_en <= $time; |
end else begin |
$display ("%m: at time %t ERROR: %s %d Illegal ODT Rtt = %d", $time, cmd_string[cmd], bank, odt_rtt); |
odt_en = 0; |
end |
// Additive Latency |
additive_latency = addr[5:3]; |
read_latency = cas_latency + additive_latency; |
write_latency = read_latency - 1; |
if ((additive_latency >= AL_MIN) && (additive_latency <= AL_MAX)) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d Additive Latency = %d", $time, cmd_string[cmd], bank, additive_latency); |
end else begin |
$display ("%m: at time %t ERROR: %s %d Illegal Additive Latency = %d", $time, cmd_string[cmd], bank, additive_latency); |
end |
// OCD Program |
ocd = addr[9:7]; |
if (ocd == 3'b000) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d OCD Program = OCD Exit", $time, cmd_string[cmd], bank); |
end else if (ocd == 3'b111) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d OCD Program = OCD Default", $time, cmd_string[cmd], bank); |
end else begin |
$display ("%m: at time %t ERROR: %s %d Illegal OCD Program = %b", $time, cmd_string[cmd], bank, ocd); |
end |
|
// DQS_N Enable |
dqs_n_en = !addr[10]; |
if (!dqs_n_en) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d DQS_N Enable = Disabled", $time, cmd_string[cmd], bank); |
end else if (dqs_n_en) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d DQS_N Enable = Enabled", $time, cmd_string[cmd], bank); |
end else begin |
$display ("%m: at time %t ERROR: %s %d Illegal DQS_N Enable = %d", $time, cmd_string[cmd], bank, dqs_n_en); |
end |
// RDQS Enable |
rdqs_en = addr[11]; |
if (!rdqs_en) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d RDQS Enable = Disabled", $time, cmd_string[cmd], bank); |
end else if (rdqs_en) begin |
`ifdef x8 |
if (DEBUG) $display ("%m: at time %t INFO: %s %d RDQS Enable = Enabled", $time, cmd_string[cmd], bank); |
`else |
$display ("%m: at time %t WARNING: %s %d Illegal RDQS Enable. RDQS only exists on a x8 part", $time, cmd_string[cmd], bank); |
rdqs_en = 0; |
`endif |
end else begin |
$display ("%m: at time %t ERROR: %s %d Illegal RDQS Enable = %d", $time, cmd_string[cmd], bank, rdqs_en); |
end |
// Output Enable |
out_en = !addr[12]; |
if (!out_en) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d Output Enable = Disabled", $time, cmd_string[cmd], bank); |
end else if (out_en) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d Output Enable = Enabled", $time, cmd_string[cmd], bank); |
end else begin |
$display ("%m: at time %t ERROR: %s %d Illegal Output Enable = %d", $time, cmd_string[cmd], bank, out_en); |
end |
end |
2 : begin |
// High Temperature Self Refresh rate |
if (!addr[7]) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d High Temperature Self Refresh rate = Disabled", $time, cmd_string[cmd], bank); |
end else if (addr[1]) begin |
if (DEBUG) $display ("%m: at time %t INFO: %s %d High Temperature Self Refresh rate = Enabled", $time, cmd_string[cmd], bank); |
end else begin |
$display ("%m: at time %t ERROR: %s %d Illegal High Temperature Self Refresh rate = %d", $time, cmd_string[cmd], bank, addr[7]); |
end |
if ((addr & ~(1<<7)) !== 0) begin |
$display ("%m: at time %t ERROR: %s %d Illegal value. Reserved bits must be programmed to zero", $time, cmd_string[cmd], bank); |
end |
end |
3 : begin |
if (addr !== 0) begin |
$display ("%m: at time %t ERROR: %s %d Illegal value. Reserved bits must be programmed to zero", $time, cmd_string[cmd], bank); |
end |
end |
endcase |
init_mode_reg[bank] = 1; |
ck_load_mode <= ck_cntr; |
end |
end |
REFRESH : begin |
if (|active_bank) begin |
$display ("%m: at time %t ERROR: %s Failure. All banks must be Precharged.", $time, cmd_string[cmd]); |
if (STOP_ON_ERROR) $stop(0); |
end else begin |
if (DEBUG) $display ("%m: at time %t INFO: %s", $time, cmd_string[cmd]); |
er_trfc_max = 0; |
ref_cntr = ref_cntr + 1; |
tm_refresh <= $time; |
end |
end |
PRECHARGE : begin |
if (addr[AP]) begin |
// tRPA timing applies when the PRECHARGE (ALL) command is issued, regardless of |
// the number of banks already open or closed. |
for (i=0; i<`BANKS; i=i+1) begin |
for (j=0; j<NOP; j=j+1) begin |
chk_err(1'b0, i, j, cmd); |
chk_err(1'b1, i, j, cmd); |
end |
chk_err(1'b0, i, PWR_DOWN, cmd); |
chk_err(1'b0, i, SELF_REF, cmd); |
end |
if (|auto_precharge_bank) begin |
$display ("%m: at time %t ERROR: %s All Failure. Auto Precharge is scheduled.", $time, cmd_string[cmd]); |
if (STOP_ON_ERROR) $stop(0); |
end else begin |
if (DEBUG) $display ("%m: at time %t INFO: %s All", $time, cmd_string[cmd]); |
active_bank = 0; |
tm_precharge_all <= $time; |
end |
end else begin |
// A PRECHARGE command is allowed if there is no open row in that bank (idle state) |
// or if the previously open row is already in the process of precharging. |
// However, the precharge period will be determined by the last PRECHARGE command issued to the bank. |
if (auto_precharge_bank[bank]) begin |
$display ("%m: at time %t ERROR: %s Failure. Auto Precharge is scheduled to bank %d.", $time, cmd_string[cmd], bank); |
if (STOP_ON_ERROR) $stop(0); |
end else begin |
if (DEBUG) $display ("%m: at time %t INFO: %s bank %d", $time, cmd_string[cmd], bank); |
active_bank[bank] = 1'b0; |
tm_bank_precharge[bank] <= $time; |
tm_precharge <= $time; |
end |
end |
end |
ACTIVATE : begin |
if (`BANKS == 8) begin |
tfaw_cntr = 0; |
for (i=0; i<`BANKS; i=i+1) begin |
if ($time - tm_bank_activate[i] < TFAW) begin |
tfaw_cntr = tfaw_cntr + 1; |
end |
end |
if (tfaw_cntr > 3) begin |
$display ("%m: at time %t ERROR: tFAW violation during %s to bank %d", $time, cmd_string[cmd], bank); |
end |
end |
|
if (!init_done) begin |
$display ("%m: at time %t ERROR: %s Failure. Initialization sequence is not complete.", $time, cmd_string[cmd]); |
if (STOP_ON_ERROR) $stop(0); |
end else if (active_bank[bank]) begin |
$display ("%m: at time %t ERROR: %s Failure. Bank %d must be Precharged.", $time, cmd_string[cmd], bank); |
if (STOP_ON_ERROR) $stop(0); |
end else begin |
if (addr >= 1<<ROW_BITS) begin |
$display ("%m: at time %t WARNING: row = %h does not exist. Maximum row = %h", $time, addr, (1<<ROW_BITS)-1); |
end |
if (DEBUG) $display ("%m: at time %t INFO: %s bank %d row %h", $time, cmd_string[cmd], bank, addr); |
active_bank[bank] = 1'b1; |
active_row[bank] = addr; |
tm_bank_activate[bank] <= $time; |
tm_activate <= $time; |
end |
|
end |
WRITE : begin |
if (!init_done) begin |
$display ("%m: at time %t ERROR: %s Failure. Initialization sequence is not complete.", $time, cmd_string[cmd]); |
if (STOP_ON_ERROR) $stop(0); |
end else if (!active_bank[bank]) begin |
$display ("%m: at time %t ERROR: %s Failure. Bank %d must be Activated.", $time, cmd_string[cmd], bank); |
if (STOP_ON_ERROR) $stop(0); |
end else if (auto_precharge_bank[bank]) begin |
$display ("%m: at time %t ERROR: %s Failure. Auto Precharge is scheduled to bank %d.", $time, cmd_string[cmd], bank); |
if (STOP_ON_ERROR) $stop(0); |
end else if ((ck_cntr - ck_write < burst_length/2) && (ck_cntr - ck_write)%2) begin |
$display ("%m: at time %t ERROR: %s Failure. Illegal burst interruption.", $time, cmd_string[cmd]); |
if (STOP_ON_ERROR) $stop(0); |
end else begin |
if (addr[AP]) begin |
auto_precharge_bank[bank] = 1'b1; |
write_precharge_bank[bank] = 1'b1; |
end |
col = ((addr>>1) & -1*(1<<AP)) | (addr & {AP{1'b1}}); |
if (col >= 1<<COL_BITS) begin |
$display ("%m: at time %t WARNING: col = %h does not exist. Maximum col = %h", $time, col, (1<<COL_BITS)-1); |
end |
if (DEBUG) $display ("%m: at time %t INFO: %s bank %d col %h, auto precharge %d", $time, cmd_string[cmd], bank, col, addr[AP]); |
wr_pipeline[2*write_latency + 1] = 1; |
ba_pipeline[2*write_latency + 1] = bank; |
row_pipeline[2*write_latency + 1] = active_row[bank]; |
col_pipeline[2*write_latency + 1] = col; |
ck_bank_write[bank] <= ck_cntr; |
ck_write <= ck_cntr; |
end |
end |
READ : begin |
if (!dll_locked) |
$display ("%m: at time %t WARNING: %s prior to DLL locked. Failing to wait for synchronization to occur may result in a violation of the tAC or tDQSCK parameters.", $time, cmd_string[cmd]); |
if (!init_done) begin |
$display ("%m: at time %t ERROR: %s Failure. Initialization sequence is not complete.", $time, cmd_string[cmd]); |
if (STOP_ON_ERROR) $stop(0); |
end else if (!active_bank[bank]) begin |
$display ("%m: at time %t ERROR: %s Failure. Bank %d must be Activated.", $time, cmd_string[cmd], bank); |
if (STOP_ON_ERROR) $stop(0); |
end else if (auto_precharge_bank[bank]) begin |
$display ("%m: at time %t ERROR: %s Failure. Auto Precharge is scheduled to bank %d.", $time, cmd_string[cmd], bank); |
if (STOP_ON_ERROR) $stop(0); |
end else if ((ck_cntr - ck_read < burst_length/2) && (ck_cntr - ck_read)%2) begin |
$display ("%m: at time %t ERROR: %s Failure. Illegal burst interruption.", $time, cmd_string[cmd]); |
if (STOP_ON_ERROR) $stop(0); |
end else begin |
if (addr[AP]) begin |
auto_precharge_bank[bank] = 1'b1; |
read_precharge_bank[bank] = 1'b1; |
end |
col = ((addr>>1) & -1*(1<<AP)) | (addr & {AP{1'b1}}); |
if (col >= 1<<COL_BITS) begin |
$display ("%m: at time %t WARNING: col = %h does not exist. Maximum col = %h", $time, col, (1<<COL_BITS)-1); |
end |
if (DEBUG) $display ("%m: at time %t INFO: %s bank %d col %h, auto precharge %d", $time, cmd_string[cmd], bank, col, addr[AP]); |
rd_pipeline[2*read_latency - 1] = 1; |
ba_pipeline[2*read_latency - 1] = bank; |
row_pipeline[2*read_latency - 1] = active_row[bank]; |
col_pipeline[2*read_latency - 1] = col; |
ck_bank_read[bank] <= ck_cntr; |
ck_read <= ck_cntr; |
end |
end |
NOP: begin |
if (in_power_down) begin |
if (DEBUG) $display ("%m: at time %t INFO: Power Down Exit", $time); |
in_power_down = 0; |
if (|active_bank & low_power) begin // slow exit active power down |
ck_slow_exit_pd <= ck_cntr; |
end |
ck_power_down <= ck_cntr; |
end |
if (in_self_refresh) begin |
if ($time - tm_cke < TISXR) |
$display ("%m: at time %t ERROR: tISXR violation during Self Refresh Exit", $time); |
if (DEBUG) $display ("%m: at time %t INFO: Self Refresh Exit", $time); |
in_self_refresh = 0; |
ck_dll_reset <= ck_cntr; |
ck_self_refresh <= ck_cntr; |
tm_self_refresh <= $time; |
tm_refresh <= $time; |
end |
end |
endcase |
if ((prev_cke !== 1) && (cmd !== NOP)) begin |
$display ("%m: at time %t ERROR: NOP or Deselect is required when CKE goes active.", $time); |
end |
if (!init_done) begin |
case (init_step) |
0 : begin |
if ($time < 200000000) |
$display ("%m: at time %t WARNING: 200 us is required before CKE goes active.", $time); |
// if (cmd_chk + 200000000 > $time) |
// $display("%m: at time %t WARNING: NOP or DESELECT is required for 200 us before CKE is brought high", $time); |
init_step = init_step + 1; |
end |
1 : if (dll_en) init_step = init_step + 1; |
2 : begin |
if (&init_mode_reg && dll_reset) begin |
active_bank = {`BANKS{1'b1}}; // require Precharge All or bank Precharges |
ref_cntr = 0; // require refresh |
init_step = init_step + 1; |
end |
end |
3 : if (ref_cntr == 2) begin |
init_step = init_step + 1; |
end |
4 : if (!dll_reset) init_step = init_step + 1; |
5 : if (ocd == 3'b111) init_step = init_step + 1; |
6 : begin |
if (ocd == 3'b000) begin |
if (DEBUG) $display ("%m: at time %t INFO: Initialization Sequence is complete", $time); |
init_done = 1; |
end |
end |
endcase |
end |
end else if (prev_cke) begin |
if ((!init_done) && (init_step > 1)) begin |
$display ("%m: at time %t ERROR: CKE must remain active until the initialization sequence is complete.", $time); |
if (STOP_ON_ERROR) $stop(0); |
end |
case (cmd) |
REFRESH : begin |
for (j=0; j<NOP; j=j+1) begin |
chk_err(1'b0, bank, j, SELF_REF); |
end |
chk_err(1'b0, bank, PWR_DOWN, SELF_REF); |
chk_err(1'b0, bank, SELF_REF, SELF_REF); |
if (|active_bank) begin |
$display ("%m: at time %t ERROR: Self Refresh Failure. All banks must be Precharged.", $time); |
if (STOP_ON_ERROR) $stop(0); |
init_done = 0; |
end else if (odt_en && odt_state) begin |
$display ("%m: at time %t ERROR: ODT must be off prior to entering Self Refresh", $time); |
if (STOP_ON_ERROR) $stop(0); |
init_done = 0; |
end else if (!init_done) begin |
$display ("%m: at time %t ERROR: Self Refresh Failure. Initialization sequence is not complete.", $time); |
if (STOP_ON_ERROR) $stop(0); |
end else begin |
if (DEBUG) $display ("%m: at time %t INFO: Self Refresh Enter", $time); |
in_self_refresh = 1; |
dll_locked = 0; |
end |
end |
NOP : begin |
// entering slow_exit or precharge power down and tANPD has not been satisfied |
if ((low_power || (active_bank == 0)) && (ck_cntr - ck_odt < TANPD)) |
$display ("%m: at time %t WARNING: tANPD violation during %s. Synchronous or asynchronous change in termination resistance is possible.", $time, cmd_string[PWR_DOWN]); |
for (j=0; j<NOP; j=j+1) begin |
chk_err(1'b0, bank, j, PWR_DOWN); |
end |
chk_err(1'b0, bank, PWR_DOWN, PWR_DOWN); |
chk_err(1'b0, bank, SELF_REF, PWR_DOWN); |
|
if (!init_done) begin |
$display ("%m: at time %t ERROR: Power Down Failure. Initialization sequence is not complete.", $time); |
if (STOP_ON_ERROR) $stop(0); |
end else begin |
if (DEBUG) begin |
if (|active_bank) begin |
$display ("%m: at time %t INFO: Active Power Down Enter", $time); |
end else begin |
$display ("%m: at time %t INFO: Precharge Power Down Enter", $time); |
end |
end |
in_power_down = 1; |
end |
end |
default : begin |
$display ("%m: at time %t ERROR: NOP, Deselect, or Refresh is required when CKE goes inactive.", $time); |
init_done = 0; |
end |
endcase |
if (!init_done) begin |
if (DEBUG) $display ("%m: at time %t WARNING: Reset has occurred. Device must be re-initialized.", $time); |
reset_task; |
end |
end |
prev_cke = cke; |
end |
endtask |
|
task data_task; |
reg [BA_BITS-1:0] bank; |
reg [ROW_BITS-1:0] row; |
reg [COL_BITS-1:0] col; |
integer i; |
integer j; |
begin |
|
if (diff_ck) begin |
for (i=0; i<36; i=i+1) begin |
if (dq_in_valid && dll_locked && ($time - tm_dqs_neg[i] < $rtoi(TDSS*tck_avg))) |
$display ("%m: at time %t ERROR: tDSS violation on %s bit %d", $time, dqs_string[i/18], i%18); |
if (check_write_dqs_high[i]) |
$display ("%m: at time %t ERROR: %s bit %d latching edge required during the preceding clock period.", $time, dqs_string[i/18], i%18); |
end |
check_write_dqs_high <= 0; |
end else begin |
for (i=0; i<36; i=i+1) begin |
if (dll_locked && dq_in_valid) begin |
tm_tdqss = abs_value(1.0*tm_ck_pos - tm_dqss_pos[i]); |
if ((tm_tdqss < tck_avg/2.0) && (tm_tdqss > TDQSS*tck_avg)) |
$display ("%m: at time %t ERROR: tDQSS violation on %s bit %d", $time, dqs_string[i/18], i%18); |
end |
if (check_write_dqs_low[i]) |
$display ("%m: at time %t ERROR: %s bit %d latching edge required during the preceding clock period", $time, dqs_string[i/18], i%18); |
end |
check_write_preamble <= 0; |
check_write_postamble <= 0; |
check_write_dqs_low <= 0; |
end |
|
if (wr_pipeline[0] || rd_pipeline[0]) begin |
bank = ba_pipeline[0]; |
row = row_pipeline[0]; |
col = col_pipeline[0]; |
burst_cntr = 0; |
memory_read(bank, row, col, memory_data); |
end |
|
// burst counter |
if (burst_cntr < burst_length) begin |
burst_position = col ^ burst_cntr; |
if (!burst_order) begin |
burst_position[BO_BITS-1:0] = col + burst_cntr; |
end |
burst_cntr = burst_cntr + 1; |
end |
|
// write dqs counter |
if (wr_pipeline[WDQS_PRE + 1]) begin |
wdqs_cntr = WDQS_PRE + burst_length + WDQS_PST - 1; |
end |
// write dqs |
if ((wdqs_cntr == burst_length + WDQS_PST) && (wdq_cntr == 0)) begin //write preamble |
check_write_preamble <= ({DQS_BITS{dqs_n_en}}<<18) | {DQS_BITS{1'b1}}; |
end |
if (wdqs_cntr > 1) begin // write data |
if ((wdqs_cntr - WDQS_PST)%2) begin |
check_write_dqs_high <= ({DQS_BITS{dqs_n_en}}<<18) | {DQS_BITS{1'b1}}; |
end else begin |
check_write_dqs_low <= ({DQS_BITS{dqs_n_en}}<<18) | {DQS_BITS{1'b1}}; |
end |
end |
if (wdqs_cntr == WDQS_PST) begin // write postamble |
check_write_postamble <= ({DQS_BITS{dqs_n_en}}<<18) | {DQS_BITS{1'b1}}; |
end |
if (wdqs_cntr > 0) begin |
wdqs_cntr = wdqs_cntr - 1; |
end |
|
// write dq |
if (dq_in_valid) begin // write data |
bit_mask = 0; |
if (diff_ck) begin |
for (i=0; i<DM_BITS; i=i+1) begin |
bit_mask = bit_mask | ({`DQ_PER_DQS{~dm_in_neg[i]}}<<(burst_position*DQ_BITS + i*`DQ_PER_DQS)); |
end |
memory_data = (dq_in_neg<<(burst_position*DQ_BITS) & bit_mask) | (memory_data & ~bit_mask); |
end else begin |
for (i=0; i<DM_BITS; i=i+1) begin |
bit_mask = bit_mask | ({`DQ_PER_DQS{~dm_in_pos[i]}}<<(burst_position*DQ_BITS + i*`DQ_PER_DQS)); |
end |
memory_data = (dq_in_pos<<(burst_position*DQ_BITS) & bit_mask) | (memory_data & ~bit_mask); |
end |
dq_temp = memory_data>>(burst_position*DQ_BITS); |
if (DEBUG) $display ("%m: at time %t INFO: WRITE @ DQS= bank = %h row = %h col = %h data = %h",$time, bank, row, (-1*BL_MAX & col) + burst_position, dq_temp); |
if (burst_cntr%BL_MIN == 0) begin |
memory_write(bank, row, col, memory_data); |
end |
end |
if (wr_pipeline[1]) begin |
wdq_cntr = burst_length; |
end |
if (wdq_cntr > 0) begin |
wdq_cntr = wdq_cntr - 1; |
dq_in_valid = 1'b1; |
end else begin |
dq_in_valid = 1'b0; |
dqs_in_valid <= 1'b0; |
for (i=0; i<36; i=i+1) begin |
wdqs_pos_cntr[i] <= 0; |
end |
end |
if (wr_pipeline[0]) begin |
b2b_write <= 1'b0; |
end |
if (wr_pipeline[2]) begin |
if (dqs_in_valid) begin |
b2b_write <= 1'b1; |
end |
dqs_in_valid <= 1'b1; |
end |
// read dqs enable counter |
if (rd_pipeline[RDQSEN_PRE]) begin |
rdqsen_cntr = RDQSEN_PRE + burst_length + RDQSEN_PST - 1; |
end |
if (rdqsen_cntr > 0) begin |
rdqsen_cntr = rdqsen_cntr - 1; |
dqs_out_en = 1'b1; |
end else begin |
dqs_out_en = 1'b0; |
end |
|
// read dqs counter |
if (rd_pipeline[RDQS_PRE]) begin |
rdqs_cntr = RDQS_PRE + burst_length + RDQS_PST - 1; |
end |
// read dqs |
if ((rdqs_cntr >= burst_length + RDQS_PST) && (rdq_cntr == 0)) begin //read preamble |
dqs_out = 1'b0; |
end else if (rdqs_cntr > RDQS_PST) begin // read data |
dqs_out = rdqs_cntr - RDQS_PST; |
end else if (rdqs_cntr > 0) begin // read postamble |
dqs_out = 1'b0; |
end else begin |
dqs_out = 1'b1; |
end |
if (rdqs_cntr > 0) begin |
rdqs_cntr = rdqs_cntr - 1; |
end |
|
// read dq enable counter |
if (rd_pipeline[RDQEN_PRE]) begin |
rdqen_cntr = RDQEN_PRE + burst_length + RDQEN_PST; |
end |
if (rdqen_cntr > 0) begin |
rdqen_cntr = rdqen_cntr - 1; |
dq_out_en = 1'b1; |
end else begin |
dq_out_en = 1'b0; |
end |
// read dq |
if (rd_pipeline[0]) begin |
rdq_cntr = burst_length; |
end |
if (rdq_cntr > 0) begin // read data |
dq_temp = memory_data>>(burst_position*DQ_BITS); |
dq_out = dq_temp; |
if (DEBUG) $display ("%m: at time %t INFO: READ @ DQS= bank = %h row = %h col = %h data = %h",$time, bank, row, (-1*BL_MAX & col) + burst_position, dq_temp); |
rdq_cntr = rdq_cntr - 1; |
end else begin |
dq_out = {DQ_BITS{1'b1}}; |
end |
|
// delay signals prior to output |
if (RANDOM_OUT_DELAY && (dqs_out_en || |dqs_out_en_dly || dq_out_en || |dq_out_en_dly)) begin |
for (i=0; i<DQS_BITS; i=i+1) begin |
// DQSCK requirements |
// 1.) less than tDQSCK |
// 2.) greater than -tDQSCK |
// 3.) cannot change more than tQHS + tDQSQ from previous DQS edge |
dqsck_max = TDQSCK; |
if (dqsck_max > dqsck[i] + TQHS + TDQSQ) begin |
dqsck_max = dqsck[i] + TQHS + TDQSQ; |
end |
dqsck_min = -1*TDQSCK; |
if (dqsck_min < dqsck[i] - TQHS - TDQSQ) begin |
dqsck_min = dqsck[i] - TQHS - TDQSQ; |
end |
|
// DQSQ requirements |
// 1.) less than tAC - DQSCK |
// 2.) less than tDQSQ |
// 3.) greater than -tAC |
// 4.) greater than tQH from previous DQS edge |
dqsq_min = -1*TAC; |
if (dqsq_min < dqsck[i] - TQHS) begin |
dqsq_min = dqsck[i] - TQHS; |
end |
if (dqsck_min == dqsck_max) begin |
dqsck[i] = dqsck_min; |
end else begin |
dqsck[i] = $dist_uniform(seed, dqsck_min, dqsck_max); |
end |
dqsq_max = TAC; |
if (dqsq_max > TDQSQ + dqsck[i]) begin |
dqsq_max = TDQSQ + dqsck[i]; |
end |
|
dqs_out_en_dly[i] <= #(tck_avg/2.0 + ($random % TAC)) dqs_out_en; |
dqs_out_dly[i] <= #(tck_avg/2.0 + dqsck[i]) dqs_out; |
for (j=0; j<`DQ_PER_DQS; j=j+1) begin |
if (dq_out_en) begin // tLZ2 |
dq_out_en_dly[i*`DQ_PER_DQS + j] <= #(tck_avg/2.0 + $dist_uniform(seed, -2*TAC, dqsq_max)) dq_out_en; |
end else begin // tHZ |
dq_out_en_dly[i*`DQ_PER_DQS + j] <= #(tck_avg/2.0 + ($random % TAC)) dq_out_en; |
end |
if (dqsq_min == dqsq_max) begin |
dq_out_dly [i*`DQ_PER_DQS + j] <= #(tck_avg/2.0 + dqsq_min) dq_out[i*`DQ_PER_DQS + j]; |
end else begin |
dq_out_dly [i*`DQ_PER_DQS + j] <= #(tck_avg/2.0 + $dist_uniform(seed, dqsq_min, dqsq_max)) dq_out[i*`DQ_PER_DQS + j]; |
end |
end |
end |
end else begin |
out_delay = tck_avg/2.0; |
dqs_out_en_dly <= #(out_delay) {DQS_BITS{dqs_out_en}}; |
dqs_out_dly <= #(out_delay) {DQS_BITS{dqs_out }}; |
dq_out_en_dly <= #(out_delay) {DQ_BITS {dq_out_en }}; |
dq_out_dly <= #(out_delay) {DQ_BITS {dq_out }}; |
end |
end |
endtask |
|
always @(diff_ck) begin : main |
integer i; |
|
if (!in_self_refresh && (diff_ck !== 1'b0) && (diff_ck !== 1'b1)) |
$display ("%m: at time %t ERROR: CK and CK_N are not allowed to go to an unknown state.", $time); |
data_task; |
if (diff_ck) begin |
// check setup of command signals |
if ($time > TIS) begin |
if ($time - tm_cke < TIS) |
$display ("%m: at time %t ERROR: tIS violation on CKE by %t", $time, tm_cke + TIS - $time); |
if (cke_in) begin |
for (i=0; i<22; i=i+1) begin |
if ($time - tm_cmd_addr[i] < TIS) |
$display ("%m: at time %t ERROR: tIS violation on %s by %t", $time, cmd_addr_string[i], tm_cmd_addr[i] + TIS - $time); |
end |
end |
end |
|
// update current state |
if (!dll_locked && !in_self_refresh && (ck_cntr - ck_dll_reset == TDLLK)) begin |
// check CL value against the clock frequency |
if (cas_latency*tck_avg < CL_TIME) |
$display ("%m: at time %t ERROR: CAS Latency = %d is illegal @tCK(avg) = %f", $time, cas_latency, tck_avg); |
// check WR value against the clock frequency |
if (write_recovery*tck_avg < TWR) |
$display ("%m: at time %t ERROR: Write Recovery = %d is illegal @tCK(avg) = %f", $time, write_recovery, tck_avg); |
dll_locked = 1; |
end |
if (|auto_precharge_bank) begin |
for (i=0; i<`BANKS; i=i+1) begin |
// Write with Auto Precharge Calculation |
// 1. Meet minimum tRAS requirement |
// 2. Write Latency PLUS BL/2 cycles PLUS WR after Write command |
if (write_precharge_bank[i] |
&& ($time - tm_bank_activate[i] >= TRAS_MIN) |
&& (ck_cntr - ck_bank_write[i] >= write_latency + burst_length/2 + write_recovery)) begin |
|
if (DEBUG) $display ("%m: at time %t INFO: Auto Precharge bank %d", $time, i); |
write_precharge_bank[i] = 0; |
active_bank[i] = 0; |
auto_precharge_bank[i] = 0; |
ck_write_ap = ck_cntr; |
tm_bank_precharge[i] = $time; |
tm_precharge = $time; |
end |
// Read with Auto Precharge Calculation |
// 1. Meet minimum tRAS requirement |
// 2. Additive Latency plus BL/2 cycles after Read command |
// 3. tRTP after the last 4-bit prefetch |
if (read_precharge_bank[i] |
&& ($time - tm_bank_activate[i] >= TRAS_MIN) |
&& (ck_cntr - ck_bank_read[i] >= additive_latency + burst_length/2)) begin |
|
read_precharge_bank[i] = 0; |
// In case the internal precharge is pushed out by tRTP, tRP starts at the point where |
// the internal precharge happens (not at the next rising clock edge after this event). |
if ($time - tm_bank_read_end[i] < TRTP) begin |
if (DEBUG) $display ("%m: at time %t INFO: Auto Precharge bank %d", tm_bank_read_end[i] + TRTP, i); |
active_bank[i] <= #(tm_bank_read_end[i] + TRTP - $time) 0; |
auto_precharge_bank[i] <= #(tm_bank_read_end[i] + TRTP - $time) 0; |
tm_bank_precharge[i] <= #(tm_bank_read_end[i] + TRTP - $time) tm_bank_read_end[i] + TRTP; |
tm_precharge <= #(tm_bank_read_end[i] + TRTP - $time) tm_bank_read_end[i] + TRTP; |
end else begin |
if (DEBUG) $display ("%m: at time %t INFO: Auto Precharge bank %d", $time, i); |
active_bank[i] = 0; |
auto_precharge_bank[i] = 0; |
tm_bank_precharge[i] = $time; |
tm_precharge = $time; |
end |
end |
end |
end |
|
// respond to incoming command |
if (cke_in ^ prev_cke) begin |
ck_cke <= ck_cntr; |
end |
|
cmd_task(cke_in, cmd_n_in, ba_in, addr_in); |
if ((cmd_n_in == WRITE) || (cmd_n_in == READ)) begin |
al_pipeline[2*additive_latency] = 1'b1; |
end |
if (al_pipeline[0]) begin |
// check tRCD after additive latency |
if ($time - tm_bank_activate[ba_pipeline[2*cas_latency - 1]] < TRCD) begin |
if (rd_pipeline[2*cas_latency - 1]) begin |
$display ("%m: at time %t ERROR: tRCD violation during %s", $time, cmd_string[READ]); |
end else begin |
$display ("%m: at time %t ERROR: tRCD violation during %s", $time, cmd_string[WRITE]); |
end |
end |
// check tWTR after additive latency |
if (rd_pipeline[2*cas_latency - 1]) begin |
if ($time - tm_write_end < TWTR) |
$display ("%m: at time %t ERROR: tWTR violation during %s", $time, cmd_string[READ]); |
end |
end |
if (rd_pipeline[2*(cas_latency - burst_length/2 + 2) - 1]) begin |
tm_bank_read_end[ba_pipeline[2*(cas_latency - burst_length/2 + 2) - 1]] <= $time; |
end |
for (i=0; i<`BANKS; i=i+1) begin |
if ((ck_cntr - ck_bank_write[i] > write_latency) && (ck_cntr - ck_bank_write[i] <= write_latency + burst_length/2)) begin |
tm_bank_write_end[i] <= $time; |
tm_write_end <= $time; |
end |
end |
|
// clk pin is disabled during self refresh |
if (!in_self_refresh) begin |
tjit_cc_time = $time - tm_ck_pos - tck_i; |
tck_i = $time - tm_ck_pos; |
tck_avg = tck_avg - tck_sample[ck_cntr%TDLLK]/$itor(TDLLK); |
tck_avg = tck_avg + tck_i/$itor(TDLLK); |
tck_sample[ck_cntr%TDLLK] = tck_i; |
tjit_per_rtime = tck_i - tck_avg; |
|
if (dll_locked) begin |
// check accumulated error |
terr_nper_rtime = 0; |
for (i=0; i<50; i=i+1) begin |
terr_nper_rtime = terr_nper_rtime + tck_sample[i] - tck_avg; |
terr_nper_rtime = abs_value(terr_nper_rtime); |
case (i) |
0 :; |
1 : if (terr_nper_rtime - TERR_2PER >= 1.0) $display ("%m: at time %t ERROR: tERR(2per) violation by %f ps.", $time, terr_nper_rtime - TERR_2PER); |
2 : if (terr_nper_rtime - TERR_3PER >= 1.0) $display ("%m: at time %t ERROR: tERR(3per) violation by %f ps.", $time, terr_nper_rtime - TERR_3PER); |
3 : if (terr_nper_rtime - TERR_4PER >= 1.0) $display ("%m: at time %t ERROR: tERR(4per) violation by %f ps.", $time, terr_nper_rtime - TERR_4PER); |
4 : if (terr_nper_rtime - TERR_5PER >= 1.0) $display ("%m: at time %t ERROR: tERR(5per) violation by %f ps.", $time, terr_nper_rtime - TERR_5PER); |
5,6,7,8,9 : if (terr_nper_rtime - TERR_N1PER >= 1.0) $display ("%m: at time %t ERROR: tERR(n1per) violation by %f ps.", $time, terr_nper_rtime - TERR_N1PER); |
default : if (terr_nper_rtime - TERR_N2PER >= 1.0) $display ("%m: at time %t ERROR: tERR(n2per) violation by %f ps.", $time, terr_nper_rtime - TERR_N2PER); |
endcase |
end |
|
// check tCK min/max/jitter |
if (abs_value(tjit_per_rtime) - TJIT_PER >= 1.0) |
$display ("%m: at time %t ERROR: tJIT(per) violation by %f ps.", $time, abs_value(tjit_per_rtime) - TJIT_PER); |
if (abs_value(tjit_cc_time) - TJIT_CC >= 1.0) |
$display ("%m: at time %t ERROR: tJIT(cc) violation by %f ps.", $time, abs_value(tjit_cc_time) - TJIT_CC); |
if (TCK_MIN - tck_avg >= 1.0) |
$display ("%m: at time %t ERROR: tCK(avg) minimum violation by %f ps.", $time, TCK_MIN - tck_avg); |
if (tck_avg - TCK_MAX >= 1.0) |
$display ("%m: at time %t ERROR: tCK(avg) maximum violation by %f ps.", $time, tck_avg - TCK_MAX); |
if (tm_ck_pos + TCK_MIN - TJIT_PER > $time) |
$display ("%m: at time %t ERROR: tCK(abs) minimum violation by %t", $time, tm_ck_pos + TCK_MIN - TJIT_PER - $time); |
if (tm_ck_pos + TCK_MAX + TJIT_PER < $time) |
$display ("%m: at time %t ERROR: tCK(abs) maximum violation by %t", $time, $time - tm_ck_pos - TCK_MAX - TJIT_PER); |
|
// check tCL |
if (tm_ck_neg + TCL_MIN*tck_avg - TJIT_DUTY > $time) |
$display ("%m: at time %t ERROR: tCL(abs) minimum violation on CLK by %t", $time, tm_ck_neg + TCL_MIN*tck_avg - TJIT_DUTY - $time); |
if (tm_ck_neg + TCL_MAX*tck_avg + TJIT_DUTY < $time) |
$display ("%m: at time %t ERROR: tCL(abs) maximum violation on CLK by %t", $time, $time - tm_ck_neg - TCL_MAX*tck_avg - TJIT_DUTY); |
if (tcl_avg < TCL_MIN*tck_avg) |
$display ("%m: at time %t ERROR: tCL(avg) minimum violation on CLK by %t", $time, TCL_MIN*tck_avg - tcl_avg); |
if (tcl_avg > TCL_MAX*tck_avg) |
$display ("%m: at time %t ERROR: tCL(avg) maximum violation on CLK by %t", $time, tcl_avg - TCL_MAX*tck_avg); |
end |
|
// calculate the tch avg jitter |
tch_avg = tch_avg - tch_sample[ck_cntr%TDLLK]/$itor(TDLLK); |
tch_avg = tch_avg + tch_i/$itor(TDLLK); |
tch_sample[ck_cntr%TDLLK] = tch_i; |
|
// update timers/counters |
tcl_i <= $time - tm_ck_neg; |
end |
|
prev_odt <= odt_in; |
// update timers/counters |
ck_cntr <= ck_cntr + 1; |
tm_ck_pos <= $time; |
end else begin |
// clk pin is disabled during self refresh |
if (!in_self_refresh) begin |
if (dll_locked) begin |
if (tm_ck_pos + TCH_MIN*tck_avg - TJIT_DUTY > $time) |
$display ("%m: at time %t ERROR: tCH(abs) minimum violation on CLK by %t", $time, tm_ck_pos + TCH_MIN*tck_avg - TJIT_DUTY + $time); |
if (tm_ck_pos + TCH_MAX*tck_avg + TJIT_DUTY < $time) |
$display ("%m: at time %t ERROR: tCH(abs) maximum violation on CLK by %t", $time, $time - tm_ck_pos - TCH_MAX*tck_avg - TJIT_DUTY); |
if (tch_avg < TCH_MIN*tck_avg) |
$display ("%m: at time %t ERROR: tCH(avg) minimum violation on CLK by %t", $time, TCH_MIN*tck_avg - tch_avg); |
if (tch_avg > TCH_MAX*tck_avg) |
$display ("%m: at time %t ERROR: tCH(avg) maximum violation on CLK by %t", $time, tch_avg - TCH_MAX*tck_avg); |
end |
|
// calculate the tcl avg jitter |
tcl_avg = tcl_avg - tcl_sample[ck_cntr%TDLLK]/$itor(TDLLK); |
tcl_avg = tcl_avg + tcl_i/$itor(TDLLK); |
tcl_sample[ck_cntr%TDLLK] = tcl_i; |
|
// update timers/counters |
tch_i <= $time - tm_ck_pos; |
end |
tm_ck_neg <= $time; |
end |
|
// on die termination |
if (odt_en) begin |
// clk pin is disabled during self refresh |
if (!in_self_refresh && diff_ck) begin |
if ($time - tm_odt < TIS) begin |
$display ("%m: at time %t ERROR: tIS violation on ODT by %t", $time, tm_odt + TIS - $time); |
end |
if (prev_odt ^ odt_in) begin |
if (!dll_locked) |
$display ("%m: at time %t WARNING: tDLLK violation during ODT transition.", $time); |
if (odt_in && ($time - tm_odt_en < TMOD)) |
$display ("%m: at time %t ERROR: tMOD violation during ODT transition", $time); |
if ($time - tm_self_refresh < TXSNR) |
$display ("%m: at time %t ERROR: tXSNR violation during ODT transition", $time); |
if (in_self_refresh) |
$display ("%m: at time %t ERROR: Illegal ODT transition during Self Refresh.", $time); |
|
// async ODT mode applies: |
// 1.) during active power down with slow exit |
// 2.) during precharge power down |
// 3.) if tANPD has not been satisfied |
// 4.) until tAXPD has been satisfied |
if ((in_power_down && (low_power || (active_bank == 0))) || (ck_cntr - ck_slow_exit_pd < TAXPD)) begin |
if (ck_cntr - ck_slow_exit_pd < TAXPD) |
$display ("%m: at time %t WARNING: tAXPD violation during ODT transition. Synchronous or asynchronous change in termination resistance is possible.", $time); |
if (odt_in) begin |
if (DEBUG) $display ("%m: at time %t INFO: Async On Die Termination = %d", $time + TAONPD, 1'b1); |
odt_state <= #(TAONPD) 1'b1; |
end else begin |
if (DEBUG) $display ("%m: at time %t INFO: Async On Die Termination = %d", $time + TAOFPD, 1'b0); |
odt_state <= #(TAOFPD) 1'b0; |
end |
// sync ODT mode applies: |
// 1.) during normal operation |
// 2.) during active power down with fast exit |
end else begin |
if (odt_in) begin |
i = TAOND*2; |
odt_pipeline[i] = 1'b1; |
end else begin |
i = TAOFD*2; |
odt_pipeline[i] = 1'b1; |
end |
end |
ck_odt <= ck_cntr; |
end |
end |
if (odt_pipeline[0]) begin |
odt_state = ~odt_state; |
if (DEBUG) $display ("%m: at time %t INFO: Sync On Die Termination = %d", $time, odt_state); |
end |
end |
|
// shift pipelines |
if (|wr_pipeline || |rd_pipeline || |al_pipeline) begin |
al_pipeline = al_pipeline>>1; |
wr_pipeline = wr_pipeline>>1; |
rd_pipeline = rd_pipeline>>1; |
for (i=0; i<`MAX_PIPE; i=i+1) begin |
ba_pipeline[i] = ba_pipeline[i+1]; |
row_pipeline[i] = row_pipeline[i+1]; |
col_pipeline[i] = col_pipeline[i+1]; |
end |
end |
if (|odt_pipeline) begin |
odt_pipeline = odt_pipeline>>1; |
end |
end |
|
// receiver(s) |
task dqs_even_receiver; |
input [4:0] i; |
reg [71:0] bit_mask; |
begin |
bit_mask = {`DQ_PER_DQS{1'b1}}<<(i*`DQ_PER_DQS); |
if (dqs_even[i]) begin |
if (rdqs_en) begin // rdqs disables dm |
dm_in_pos[i] = 1'b0; |
end else begin |
dm_in_pos[i] = dm_in[i]; |
end |
dq_in_pos = (dq_in & bit_mask) | (dq_in_pos & ~bit_mask); |
end |
end |
endtask |
|
always @(posedge dqs_even[ 0]) dqs_even_receiver( 0); |
always @(posedge dqs_even[ 1]) dqs_even_receiver( 1); |
always @(posedge dqs_even[ 2]) dqs_even_receiver( 2); |
always @(posedge dqs_even[ 3]) dqs_even_receiver( 3); |
always @(posedge dqs_even[ 4]) dqs_even_receiver( 4); |
always @(posedge dqs_even[ 5]) dqs_even_receiver( 5); |
always @(posedge dqs_even[ 6]) dqs_even_receiver( 6); |
always @(posedge dqs_even[ 7]) dqs_even_receiver( 7); |
always @(posedge dqs_even[ 8]) dqs_even_receiver( 8); |
always @(posedge dqs_even[ 9]) dqs_even_receiver( 9); |
always @(posedge dqs_even[10]) dqs_even_receiver(10); |
always @(posedge dqs_even[11]) dqs_even_receiver(11); |
always @(posedge dqs_even[12]) dqs_even_receiver(12); |
always @(posedge dqs_even[13]) dqs_even_receiver(13); |
always @(posedge dqs_even[14]) dqs_even_receiver(14); |
always @(posedge dqs_even[15]) dqs_even_receiver(15); |
always @(posedge dqs_even[16]) dqs_even_receiver(16); |
always @(posedge dqs_even[17]) dqs_even_receiver(17); |
|
task dqs_odd_receiver; |
input [4:0] i; |
reg [71:0] bit_mask; |
begin |
bit_mask = {`DQ_PER_DQS{1'b1}}<<(i*`DQ_PER_DQS); |
if (dqs_odd[i]) begin |
if (rdqs_en) begin // rdqs disables dm |
dm_in_neg[i] = 1'b0; |
end else begin |
dm_in_neg[i] = dm_in[i]; |
end |
dq_in_neg = (dq_in & bit_mask) | (dq_in_neg & ~bit_mask); |
end |
end |
endtask |
|
always @(posedge dqs_odd[ 0]) dqs_odd_receiver( 0); |
always @(posedge dqs_odd[ 1]) dqs_odd_receiver( 1); |
always @(posedge dqs_odd[ 2]) dqs_odd_receiver( 2); |
always @(posedge dqs_odd[ 3]) dqs_odd_receiver( 3); |
always @(posedge dqs_odd[ 4]) dqs_odd_receiver( 4); |
always @(posedge dqs_odd[ 5]) dqs_odd_receiver( 5); |
always @(posedge dqs_odd[ 6]) dqs_odd_receiver( 6); |
always @(posedge dqs_odd[ 7]) dqs_odd_receiver( 7); |
always @(posedge dqs_odd[ 8]) dqs_odd_receiver( 8); |
always @(posedge dqs_odd[ 9]) dqs_odd_receiver( 9); |
always @(posedge dqs_odd[10]) dqs_odd_receiver(10); |
always @(posedge dqs_odd[11]) dqs_odd_receiver(11); |
always @(posedge dqs_odd[12]) dqs_odd_receiver(12); |
always @(posedge dqs_odd[13]) dqs_odd_receiver(13); |
always @(posedge dqs_odd[14]) dqs_odd_receiver(14); |
always @(posedge dqs_odd[15]) dqs_odd_receiver(15); |
always @(posedge dqs_odd[16]) dqs_odd_receiver(16); |
always @(posedge dqs_odd[17]) dqs_odd_receiver(17); |
|
// Processes to check hold and pulse width of control signals |
always @(cke_in) begin |
if ($time > TIH) begin |
if ($time - tm_ck_pos < TIH) |
$display ("%m: at time %t ERROR: tIH violation on CKE by %t", $time, tm_ck_pos + TIH - $time); |
end |
if (dll_locked && ($time - tm_cke < $rtoi(TIPW*tck_avg))) |
$display ("%m: at time %t ERROR: tIPW violation on CKE by %t", $time, tm_cke + TIPW*tck_avg - $time); |
tm_cke = $time; |
end |
always @(odt_in) begin |
if (odt_en && !in_self_refresh) begin |
if ($time - tm_ck_pos < TIH) |
$display ("%m: at time %t ERROR: tIH violation on ODT by %t", $time, tm_ck_pos + TIH - $time); |
if (dll_locked && ($time - tm_odt < $rtoi(TIPW*tck_avg))) |
$display ("%m: at time %t ERROR: tIPW violation on ODT by %t", $time, tm_odt + TIPW*tck_avg - $time); |
end |
tm_odt = $time; |
end |
|
task cmd_addr_timing_check; |
input i; |
reg [4:0] i; |
begin |
if (prev_cke) begin |
if ($time - tm_ck_pos < TIH) |
$display ("%m: at time %t ERROR: tIH violation on %s by %t", $time, cmd_addr_string[i], tm_ck_pos + TIH - $time); |
if (dll_locked && ($time - tm_cmd_addr[i] < $rtoi(TIPW*tck_avg))) |
$display ("%m: at time %t ERROR: tIPW violation on %s by %t", $time, cmd_addr_string[i], tm_cmd_addr[i] + TIPW*tck_avg - $time); |
end |
tm_cmd_addr[i] = $time; |
end |
endtask |
|
always @(cs_n_in ) cmd_addr_timing_check( 0); |
always @(ras_n_in ) cmd_addr_timing_check( 1); |
always @(cas_n_in ) cmd_addr_timing_check( 2); |
always @(we_n_in ) cmd_addr_timing_check( 3); |
always @(ba_in [ 0]) cmd_addr_timing_check( 4); |
always @(ba_in [ 1]) cmd_addr_timing_check( 5); |
always @(ba_in [ 2]) cmd_addr_timing_check( 6); |
always @(addr_in[ 0]) cmd_addr_timing_check( 7); |
always @(addr_in[ 1]) cmd_addr_timing_check( 8); |
always @(addr_in[ 2]) cmd_addr_timing_check( 9); |
always @(addr_in[ 3]) cmd_addr_timing_check(10); |
always @(addr_in[ 4]) cmd_addr_timing_check(11); |
always @(addr_in[ 5]) cmd_addr_timing_check(12); |
always @(addr_in[ 6]) cmd_addr_timing_check(13); |
always @(addr_in[ 7]) cmd_addr_timing_check(14); |
always @(addr_in[ 8]) cmd_addr_timing_check(15); |
always @(addr_in[ 9]) cmd_addr_timing_check(16); |
always @(addr_in[10]) cmd_addr_timing_check(17); |
always @(addr_in[11]) cmd_addr_timing_check(18); |
always @(addr_in[12]) cmd_addr_timing_check(19); |
always @(addr_in[13]) cmd_addr_timing_check(20); |
always @(addr_in[14]) cmd_addr_timing_check(21); |
always @(addr_in[15]) cmd_addr_timing_check(22); |
|
// Processes to check setup and hold of data signals |
task dm_timing_check; |
input i; |
reg [4:0] i; |
begin |
if (dqs_in_valid) begin |
if ($time - tm_dqs[i] < TDH) |
$display ("%m: at time %t ERROR: tDH violation on DM bit %d by %t", $time, i, tm_dqs[i] + TDH - $time); |
if (check_dm_tdipw[i]) begin |
if (dll_locked && ($time - tm_dm[i] < $rtoi(TDIPW*tck_avg))) |
$display ("%m: at time %t ERROR: tDIPW violation on DM bit %d by %t", $time, i, tm_dm[i] + TDIPW*tck_avg - $time); |
end |
end |
check_dm_tdipw[i] <= 1'b0; |
tm_dm[i] = $time; |
end |
endtask |
|
always @(dm_in[ 0]) dm_timing_check( 0); |
always @(dm_in[ 1]) dm_timing_check( 1); |
always @(dm_in[ 2]) dm_timing_check( 2); |
always @(dm_in[ 3]) dm_timing_check( 3); |
always @(dm_in[ 4]) dm_timing_check( 4); |
always @(dm_in[ 5]) dm_timing_check( 5); |
always @(dm_in[ 6]) dm_timing_check( 6); |
always @(dm_in[ 7]) dm_timing_check( 7); |
always @(dm_in[ 8]) dm_timing_check( 8); |
always @(dm_in[ 9]) dm_timing_check( 9); |
always @(dm_in[10]) dm_timing_check(10); |
always @(dm_in[11]) dm_timing_check(11); |
always @(dm_in[12]) dm_timing_check(12); |
always @(dm_in[13]) dm_timing_check(13); |
always @(dm_in[14]) dm_timing_check(14); |
always @(dm_in[15]) dm_timing_check(15); |
always @(dm_in[16]) dm_timing_check(16); |
always @(dm_in[17]) dm_timing_check(17); |
|
task dq_timing_check; |
input i; |
reg [6:0] i; |
begin |
if (dqs_in_valid) begin |
if ($time - tm_dqs[i/`DQ_PER_DQS] < TDH) |
$display ("%m: at time %t ERROR: tDH violation on DQ bit %d by %t", $time, i, tm_dqs[i/`DQ_PER_DQS] + TDH - $time); |
if (check_dq_tdipw[i]) begin |
if (dll_locked && ($time - tm_dq[i] < $rtoi(TDIPW*tck_avg))) |
$display ("%m: at time %t ERROR: tDIPW violation on DQ bit %d by %t", $time, i, tm_dq[i] + TDIPW*tck_avg - $time); |
end |
end |
check_dq_tdipw[i] <= 1'b0; |
tm_dq[i] = $time; |
end |
endtask |
|
always @(dq_in[ 0]) dq_timing_check( 0); |
always @(dq_in[ 1]) dq_timing_check( 1); |
always @(dq_in[ 2]) dq_timing_check( 2); |
always @(dq_in[ 3]) dq_timing_check( 3); |
always @(dq_in[ 4]) dq_timing_check( 4); |
always @(dq_in[ 5]) dq_timing_check( 5); |
always @(dq_in[ 6]) dq_timing_check( 6); |
always @(dq_in[ 7]) dq_timing_check( 7); |
always @(dq_in[ 8]) dq_timing_check( 8); |
always @(dq_in[ 9]) dq_timing_check( 9); |
always @(dq_in[10]) dq_timing_check(10); |
always @(dq_in[11]) dq_timing_check(11); |
always @(dq_in[12]) dq_timing_check(12); |
always @(dq_in[13]) dq_timing_check(13); |
always @(dq_in[14]) dq_timing_check(14); |
always @(dq_in[15]) dq_timing_check(15); |
always @(dq_in[16]) dq_timing_check(16); |
always @(dq_in[17]) dq_timing_check(17); |
always @(dq_in[18]) dq_timing_check(18); |
always @(dq_in[19]) dq_timing_check(19); |
always @(dq_in[20]) dq_timing_check(20); |
always @(dq_in[21]) dq_timing_check(21); |
always @(dq_in[22]) dq_timing_check(22); |
always @(dq_in[23]) dq_timing_check(23); |
always @(dq_in[24]) dq_timing_check(24); |
always @(dq_in[25]) dq_timing_check(25); |
always @(dq_in[26]) dq_timing_check(26); |
always @(dq_in[27]) dq_timing_check(27); |
always @(dq_in[28]) dq_timing_check(28); |
always @(dq_in[29]) dq_timing_check(29); |
always @(dq_in[30]) dq_timing_check(30); |
always @(dq_in[31]) dq_timing_check(31); |
always @(dq_in[32]) dq_timing_check(32); |
always @(dq_in[33]) dq_timing_check(33); |
always @(dq_in[34]) dq_timing_check(34); |
always @(dq_in[35]) dq_timing_check(35); |
always @(dq_in[36]) dq_timing_check(36); |
always @(dq_in[37]) dq_timing_check(37); |
always @(dq_in[38]) dq_timing_check(38); |
always @(dq_in[39]) dq_timing_check(39); |
always @(dq_in[40]) dq_timing_check(40); |
always @(dq_in[41]) dq_timing_check(41); |
always @(dq_in[42]) dq_timing_check(42); |
always @(dq_in[43]) dq_timing_check(43); |
always @(dq_in[44]) dq_timing_check(44); |
always @(dq_in[45]) dq_timing_check(45); |
always @(dq_in[46]) dq_timing_check(46); |
always @(dq_in[47]) dq_timing_check(47); |
always @(dq_in[48]) dq_timing_check(48); |
always @(dq_in[49]) dq_timing_check(49); |
always @(dq_in[50]) dq_timing_check(50); |
always @(dq_in[51]) dq_timing_check(51); |
always @(dq_in[52]) dq_timing_check(52); |
always @(dq_in[53]) dq_timing_check(53); |
always @(dq_in[54]) dq_timing_check(54); |
always @(dq_in[55]) dq_timing_check(55); |
always @(dq_in[56]) dq_timing_check(56); |
always @(dq_in[57]) dq_timing_check(57); |
always @(dq_in[58]) dq_timing_check(58); |
always @(dq_in[59]) dq_timing_check(59); |
always @(dq_in[60]) dq_timing_check(60); |
always @(dq_in[61]) dq_timing_check(61); |
always @(dq_in[62]) dq_timing_check(62); |
always @(dq_in[63]) dq_timing_check(63); |
always @(dq_in[64]) dq_timing_check(64); |
always @(dq_in[65]) dq_timing_check(65); |
always @(dq_in[66]) dq_timing_check(66); |
always @(dq_in[67]) dq_timing_check(67); |
always @(dq_in[68]) dq_timing_check(68); |
always @(dq_in[69]) dq_timing_check(69); |
always @(dq_in[70]) dq_timing_check(70); |
always @(dq_in[71]) dq_timing_check(71); |
|
task dqs_pos_timing_check; |
input i; |
reg [5:0] i; |
reg [3:0] j; |
begin |
if (dqs_in_valid && ((wdqs_pos_cntr[i] < burst_length/2) || b2b_write) && (dqs_n_en || i<18)) begin |
if (dqs_in[i] ^ prev_dqs_in[i]) begin |
if (dll_locked) begin |
if (check_write_preamble[i]) begin |
if ($time - tm_dqs_neg[i] < $rtoi(TWPRE*tck_avg)) |
$display ("%m: at time %t ERROR: tWPRE violation on &s bit %d", $time, dqs_string[i/18], i%18); |
end else if (check_write_postamble[i]) begin |
if ($time - tm_dqs_neg[i] < $rtoi(TWPST*tck_avg)) |
$display ("%m: at time %t ERROR: tWPST violation on %s bit %d", $time, dqs_string[i/18], i%18); |
end else begin |
if ($time - tm_dqs_neg[i] < $rtoi(TDQSL*tck_avg)) |
$display ("%m: at time %t ERROR: tDQSL violation on %s bit %d", $time, dqs_string[i/18], i%18); |
end |
end |
if ($time - tm_dm[i%18] < TDS) |
$display ("%m: at time %t ERROR: tDS violation on DM bit %d by %t", $time, i, tm_dm[i%18] + TDS - $time); |
if (!dq_out_en) begin |
for (j=0; j<`DQ_PER_DQS; j=j+1) begin |
if ($time - tm_dq[i*`DQ_PER_DQS+j] < TDS) |
$display ("%m: at time %t ERROR: tDS violation on DQ bit %d by %t", $time, i*`DQ_PER_DQS+j, tm_dq[i*`DQ_PER_DQS+j] + TDS - $time); |
check_dq_tdipw[i*`DQ_PER_DQS+j] <= 1'b1; |
end |
end |
if ((wdqs_pos_cntr[i] < burst_length/2) && !b2b_write) begin |
wdqs_pos_cntr[i] <= wdqs_pos_cntr[i] + 1; |
end else begin |
wdqs_pos_cntr[i] <= 1; |
end |
check_dm_tdipw[i%18] <= 1'b1; |
check_write_preamble[i] <= 1'b0; |
check_write_postamble[i] <= 1'b0; |
check_write_dqs_low[i] <= 1'b0; |
tm_dqs[i%18] <= $time; |
end else begin |
$display ("%m: at time %t ERROR: Invalid latching edge on %s bit %d", $time, dqs_string[i/18], i%18); |
end |
end |
tm_dqss_pos[i] <= $time; |
tm_dqs_pos[i] = $time; |
prev_dqs_in[i] <= dqs_in[i]; |
end |
endtask |
|
always @(posedge dqs_in[ 0]) dqs_pos_timing_check( 0); |
always @(posedge dqs_in[ 1]) dqs_pos_timing_check( 1); |
always @(posedge dqs_in[ 2]) dqs_pos_timing_check( 2); |
always @(posedge dqs_in[ 3]) dqs_pos_timing_check( 3); |
always @(posedge dqs_in[ 4]) dqs_pos_timing_check( 4); |
always @(posedge dqs_in[ 5]) dqs_pos_timing_check( 5); |
always @(posedge dqs_in[ 6]) dqs_pos_timing_check( 6); |
always @(posedge dqs_in[ 7]) dqs_pos_timing_check( 7); |
always @(posedge dqs_in[ 8]) dqs_pos_timing_check( 8); |
always @(posedge dqs_in[ 9]) dqs_pos_timing_check( 9); |
always @(posedge dqs_in[10]) dqs_pos_timing_check(10); |
always @(posedge dqs_in[11]) dqs_pos_timing_check(11); |
always @(posedge dqs_in[12]) dqs_pos_timing_check(12); |
always @(posedge dqs_in[13]) dqs_pos_timing_check(13); |
always @(posedge dqs_in[14]) dqs_pos_timing_check(14); |
always @(posedge dqs_in[15]) dqs_pos_timing_check(15); |
always @(posedge dqs_in[16]) dqs_pos_timing_check(16); |
always @(posedge dqs_in[17]) dqs_pos_timing_check(17); |
always @(negedge dqs_in[18]) dqs_pos_timing_check(18); |
always @(negedge dqs_in[19]) dqs_pos_timing_check(19); |
always @(negedge dqs_in[20]) dqs_pos_timing_check(20); |
always @(negedge dqs_in[21]) dqs_pos_timing_check(21); |
always @(negedge dqs_in[22]) dqs_pos_timing_check(22); |
always @(negedge dqs_in[23]) dqs_pos_timing_check(23); |
always @(negedge dqs_in[24]) dqs_pos_timing_check(24); |
always @(negedge dqs_in[25]) dqs_pos_timing_check(25); |
always @(negedge dqs_in[26]) dqs_pos_timing_check(26); |
always @(negedge dqs_in[27]) dqs_pos_timing_check(27); |
always @(negedge dqs_in[28]) dqs_pos_timing_check(28); |
always @(negedge dqs_in[29]) dqs_pos_timing_check(29); |
always @(negedge dqs_in[30]) dqs_pos_timing_check(30); |
always @(negedge dqs_in[31]) dqs_pos_timing_check(31); |
always @(negedge dqs_in[32]) dqs_neg_timing_check(32); |
always @(negedge dqs_in[33]) dqs_neg_timing_check(33); |
always @(negedge dqs_in[34]) dqs_neg_timing_check(34); |
always @(negedge dqs_in[35]) dqs_neg_timing_check(35); |
|
task dqs_neg_timing_check; |
input i; |
reg [5:0] i; |
reg [3:0] j; |
begin |
if (dqs_in_valid && (wdqs_pos_cntr[i] > 0) && check_write_dqs_high[i] && (dqs_n_en || i < 18)) begin |
if (dqs_in[i] ^ prev_dqs_in[i]) begin |
if (dll_locked) begin |
if ($time - tm_dqs_pos[i] < $rtoi(TDQSH*tck_avg)) |
$display ("%m: at time %t ERROR: tDQSH violation on %s bit %d", $time, dqs_string[i/18], i%18); |
if ($time - tm_ck_pos < $rtoi(TDSH*tck_avg)) |
$display ("%m: at time %t ERROR: tDSH violation on %s bit %d", $time, dqs_string[i/18], i%18); |
end |
if ($time - tm_dm[i%18] < TDS) |
$display ("%m: at time %t ERROR: tDS violation on DM bit %d by %t", $time, i, tm_dm[i%18] + TDS - $time); |
if (!dq_out_en) begin |
for (j=0; j<`DQ_PER_DQS; j=j+1) begin |
if ($time - tm_dq[i*`DQ_PER_DQS+j] < TDS) |
$display ("%m: at time %t ERROR: tDS violation on DQ bit %d by %t", $time, i*`DQ_PER_DQS+j, tm_dq[i*`DQ_PER_DQS+j] + TDS - $time); |
check_dq_tdipw[i*`DQ_PER_DQS+j] <= 1'b1; |
end |
end |
check_dm_tdipw[i%18] <= 1'b1; |
check_write_dqs_high[i] <= 1'b0; |
tm_dqs[i%18] <= $time; |
end else begin |
$display ("%m: at time %t ERROR: Invalid latching edge on %s bit %d", $time, dqs_string[i/18], i%18); |
end |
end |
tm_dqs_neg[i] = $time; |
prev_dqs_in[i] <= dqs_in[i]; |
end |
endtask |
|
always @(negedge dqs_in[ 0]) dqs_neg_timing_check( 0); |
always @(negedge dqs_in[ 1]) dqs_neg_timing_check( 1); |
always @(negedge dqs_in[ 2]) dqs_neg_timing_check( 2); |
always @(negedge dqs_in[ 3]) dqs_neg_timing_check( 3); |
always @(negedge dqs_in[ 4]) dqs_neg_timing_check( 4); |
always @(negedge dqs_in[ 5]) dqs_neg_timing_check( 5); |
always @(negedge dqs_in[ 6]) dqs_neg_timing_check( 6); |
always @(negedge dqs_in[ 7]) dqs_neg_timing_check( 7); |
always @(negedge dqs_in[ 8]) dqs_neg_timing_check( 8); |
always @(negedge dqs_in[ 9]) dqs_neg_timing_check( 9); |
always @(negedge dqs_in[10]) dqs_neg_timing_check(10); |
always @(negedge dqs_in[11]) dqs_neg_timing_check(11); |
always @(negedge dqs_in[12]) dqs_neg_timing_check(12); |
always @(negedge dqs_in[13]) dqs_neg_timing_check(13); |
always @(negedge dqs_in[14]) dqs_neg_timing_check(14); |
always @(negedge dqs_in[15]) dqs_neg_timing_check(15); |
always @(negedge dqs_in[16]) dqs_neg_timing_check(16); |
always @(negedge dqs_in[17]) dqs_neg_timing_check(17); |
always @(posedge dqs_in[18]) dqs_neg_timing_check(18); |
always @(posedge dqs_in[19]) dqs_neg_timing_check(19); |
always @(posedge dqs_in[20]) dqs_neg_timing_check(20); |
always @(posedge dqs_in[21]) dqs_neg_timing_check(21); |
always @(posedge dqs_in[22]) dqs_neg_timing_check(22); |
always @(posedge dqs_in[23]) dqs_neg_timing_check(23); |
always @(posedge dqs_in[24]) dqs_neg_timing_check(24); |
always @(posedge dqs_in[25]) dqs_neg_timing_check(25); |
always @(posedge dqs_in[26]) dqs_neg_timing_check(26); |
always @(posedge dqs_in[27]) dqs_neg_timing_check(27); |
always @(posedge dqs_in[28]) dqs_neg_timing_check(28); |
always @(posedge dqs_in[29]) dqs_neg_timing_check(29); |
always @(posedge dqs_in[30]) dqs_neg_timing_check(30); |
always @(posedge dqs_in[31]) dqs_neg_timing_check(31); |
always @(posedge dqs_in[32]) dqs_neg_timing_check(32); |
always @(posedge dqs_in[33]) dqs_neg_timing_check(33); |
always @(posedge dqs_in[34]) dqs_neg_timing_check(34); |
always @(posedge dqs_in[35]) dqs_neg_timing_check(35); |
|
endmodule |
/s3adsp1800/bench/verilog/include/eth_stim.v
0,0 → 1,1562
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Ethernet MAC Stimulus //// |
//// //// |
//// Description //// |
//// Ethernet MAC stimulus tasks. Taken from the project //// |
//// testbench in the ethmac core. //// |
//// //// |
//// To Do: //// |
//// //// |
//// //// |
//// Author(s): //// |
//// - Tadej Markovic, tadej@opencores.org //// |
//// - Igor Mohor, igorM@opencores.org //// |
//// - Julius Baxter julius.baxter@orsoc.se //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009 Authors and 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
`define TIME $display("Time: %0t", $time) |
|
// Defines for ethernet test to trigger sending/receiving |
// Is straight forward when using RTL design, but if using netlist then paths to |
// the RX/TX enabled bits depend on synthesis tool, etc, but ones here appear to |
// work with design put through Synplify, with hierarchy maintained. |
`define ETH_TOP dut.ethmac0 |
`define ETH_BD_RAM_PATH `ETH_TOP.wishbone.bd_ram |
`define ETH_MODER_PATH `ETH_TOP.ethreg1.MODER_0 |
|
`ifdef RTL_SIM |
`ifdef ethmac_IS_GATELEVEL |
`define ETH_MODER_TXEN_BIT `ETH_MODER_PATH.r_TxEn; |
`define ETH_MODER_RXEN_BIT `ETH_MODER_PATH.r_RxEn; |
`else |
`define ETH_MODER_TXEN_BIT `ETH_MODER_PATH.DataOut[1]; |
`define ETH_MODER_RXEN_BIT `ETH_MODER_PATH.DataOut[0]; |
`endif |
`endif |
|
`ifdef GATE_SIM |
`define ETH_MODER_TXEN_BIT `ETH_MODER_PATH.r_TxEn; |
`define ETH_MODER_RXEN_BIT `ETH_MODER_PATH.r_RxEn; |
`endif |
|
reg [15:0] eth_stim_rx_packet_length; |
reg [7:0] st_data; |
reg [31:0] lfsr; |
integer lfsr_last_byte; |
|
// Is number of ethernet packets to send if doing the eth-rx test. |
parameter eth_stim_num_rx_only_num_packets = 12; // Set to 0 for continuous RX |
parameter eth_stim_num_rx_only_packet_size = 60; |
parameter eth_stim_num_rx_only_packet_size_change = 2'b01; // 2'b01: Increment |
parameter eth_stim_num_rx_only_packet_size_change_amount = 127; |
parameter eth_stim_num_rx_only_IPG = 800_000; // ps |
|
// Do call/response test |
reg eth_stim_do_rx_reponse_to_tx; |
reg eth_stim_do_overflow_test; |
|
parameter num_tx_bds = 16; |
parameter num_tx_bds_mask = 4'hf; |
parameter num_rx_bds = 16; |
parameter num_rx_bds_mask = 4'hf; |
parameter max_eth_packet_size = 16'h0600; |
|
// If running eth-rxtxbig test (sending and receiving maximum packets), then |
// set this parameter to the max packet size, otherwise min packet size |
//parameter rx_while_tx_min_packet_size = max_eth_packet_size; |
parameter rx_while_tx_min_packet_size = 32; |
|
// Use the smallest possible IPG |
parameter eth_stim_use_min_IPG = 0; |
parameter eth_stim_IPG_delay_max = 100_000_000; // Maximum 100 us |
//parameter eth_stim_IPG_delay_max = 100_000_000; // Maximum 100mS between packets |
parameter eth_stim_IPG_min_10mb = 9600_000; // 9.6 uS |
parameter eth_stim_IPG_min_100mb = 800_000; // 860+~100 = 960 nS 100MBit min IPG |
parameter eth_stim_check_rx_packet_contents = 1; |
parameter eth_stim_check_tx_packet_contents = 1; |
|
parameter eth_inject_errors = 0; |
|
// When running simulations where you don't want to feed packets to the design |
// like this... |
parameter eth_stim_disable_rx_stim = 0; |
|
// Delay between seeing that the buffer descriptor for an RX packet says it's |
// been received and ending up in the memory. |
// For 25MHz sdram controller, use following: |
//parameter Td_rx_packet_check = (`BOARD_CLOCK_PERIOD * 2000); |
// For 64MHz sdram controller, use following: |
parameter Td_rx_packet_check = (`BOARD_CLOCK_PERIOD * 500); |
|
integer expected_rxbd;// init to 0 |
integer expected_txbd; |
|
wire ethmac_rxen; |
wire ethmac_txen; |
assign ethmac_rxen = eth_stim_disable_rx_stim ? 0 : `ETH_MODER_RXEN_BIT; |
assign ethmac_txen = `ETH_MODER_TXEN_BIT; |
|
integer eth_rx_num_packets_sent = 0; |
integer eth_rx_num_packets_checked = 0; |
integer num_tx_packets = 1; |
|
integer rx_packet_lengths [0:1023]; // Array of packet lengths |
|
|
integer speed_loop; |
|
// When txen is (re)enabled, the tx bd pointer goes back to 0 |
always @(posedge ethmac_txen) |
expected_txbd = 0; |
|
reg eth_stim_waiting; |
|
initial |
begin |
#1; |
//lfsr = 32'h84218421; // Init pseudo lfsr |
lfsr = 32'h00700001; // Init pseudo lfsr |
lfsr_last_byte = 0; |
|
eth_stim_waiting = 1; |
expected_rxbd = num_tx_bds; // init this here |
|
eth_stim_do_rx_reponse_to_tx = 0; |
eth_stim_do_overflow_test = 0; |
|
while (eth_stim_waiting) // Loop, waiting for enabling of MAC by software |
begin |
#100; |
// If RX enable and not TX enable... |
if(ethmac_rxen === 1'b1 & !(ethmac_txen===1'b1)) |
begin |
if (eth_inject_errors) |
begin |
do_rx_only_stim(16, 64, 0, 0); |
do_rx_only_stim(128, 64, 1'b1, 8); |
do_rx_only_stim(256, 64, 1'b1, 4); |
eth_stim_waiting = 0; |
end |
else |
begin |
//do_rx_only_stim(eth_stim_num_rx_only_num_packets, |
//eth_stim_num_rx_only_packet_size, 0, 0); |
|
// Call packet send loop directly. No error injection. |
send_packet_loop(eth_stim_num_rx_only_num_packets, |
eth_stim_num_rx_only_packet_size, |
eth_stim_num_rx_only_packet_size_change, |
eth_stim_num_rx_only_packet_size_change_amount, |
eth_phy0.eth_speed, // Speed |
eth_stim_num_rx_only_IPG, // IPG |
48'h0012_3456_789a, 48'h0708_090A_0B0C, 1, |
0, 0, 0); |
|
eth_stim_waiting = 0; |
end |
end // if (ethmac_rxen === 1'b1 & !(ethmac_txen===1'b1)) |
// If both RX and TX enabled |
else if (ethmac_rxen === 1'b1 & ethmac_txen===1'b1) |
begin |
// Both enabled - let's wait for the first packet transmitted |
// to see what stimulus we should provide |
while (num_tx_packets==1) |
#1000; |
|
$display("* ethmac RX/TX test request: %x", eth_phy0.tx_mem[0]); |
|
// Check the first received byte's value |
case (eth_phy0.tx_mem[0]) |
0: |
begin |
// kickoff call/response here |
eth_stim_do_rx_reponse_to_tx = 1; |
end |
1: |
begin |
// kickoff overflow test here |
eth_stim_do_overflow_test = 1; |
end |
default: |
begin |
do_rx_while_tx_stim(1400); |
end |
endcase // case (eth_phy0.tx_mem[0]) |
|
eth_stim_waiting = 0; |
end |
end // while (eth_stim_waiting) |
|
end // initial begin |
|
// Main Ethernet RX testing stimulus task. |
// Sends a set of packets at both speeds |
task do_rx_only_stim; |
input [31:0] num_packets; |
input [31:0] start_packet_size; |
input inject_errors; |
input [31:0] inject_errors_mod; |
|
begin |
|
for(speed_loop=1;speed_loop<3;speed_loop=speed_loop+1) |
begin |
|
send_packet_loop(num_packets, start_packet_size, 2'b01, 1, |
speed_loop[0], 10000, |
48'h0012_3456_789a, 48'h0708_090A_0B0C, 1, |
inject_errors, inject_errors_mod, 0); |
|
end |
|
end |
endtask // do_rx_stim |
|
// Generate RX packets while there's TX going on |
// Sends a set of packets at both speeds |
task do_rx_while_tx_stim; |
input [31:0] num_packets; |
reg [31:0] IPG; // Inter-packet gap |
reg [31:0] packet_size; |
|
integer j; |
begin |
|
for(j=0;j<num_packets;j=j+1) |
begin |
// Determine delay between RX packets: |
|
if (eth_stim_use_min_IPG) |
begin |
// Assign based on whether we're in 100mbit or 10mbit mode |
IPG = eth_phy0.eth_speed ? eth_stim_IPG_min_100mb : |
eth_stim_IPG_min_10mb; |
// Add a little bit of variability |
// Add up to 15 |
IPG = IPG + ($random & 32'h000000f); |
end |
else |
begin |
IPG = $random; |
|
while (IPG > eth_stim_IPG_delay_max) |
IPG = IPG / 2; |
|
|
end |
$display("do_rx_while_tx IPG = %0d", IPG); |
// Determine size of next packet: |
if (rx_while_tx_min_packet_size == max_eth_packet_size) |
// We want to transmit biggest packets possible, easy case |
packet_size = max_eth_packet_size - 4; |
else |
begin |
// Constrained random sized packets |
packet_size = $random; |
|
while (packet_size > (max_eth_packet_size-4)) |
packet_size = packet_size / 2; |
|
// Now divide by least significant bits of j |
packet_size = packet_size / {29'd0,j[1:0],1'b1}; |
if (packet_size < 60) |
packet_size = packet_size + 60; |
end |
|
$display("do_rx_while_tx packet_size = %0d", packet_size); |
send_packet_loop(1, packet_size, 2'b01, 1, eth_phy0.eth_speed, |
IPG, 48'h0012_3456_789a, |
48'h0708_090A_0B0C, 1, 1'b0, 0, 0); |
|
// If RX enable went low, wait for it go high again |
if (ethmac_rxen===1'b0) |
begin |
|
while (ethmac_rxen===1'b0) |
begin |
@(posedge ethmac_rxen); |
#10000; |
end |
|
// RX disabled and when re-enabled we reset the buffer descriptor number |
expected_rxbd = num_tx_bds; |
|
end |
|
end // for (j=0;j<num_packets;j=j+1) |
end |
endtask // do_rx_stim |
|
// Registers used in detecting transmitted packets |
reg eth_stim_tx_loop_keep_polling; |
reg [31:0] ethmac_txbd_lenstat, ethmac_last_txbd_lenstat; |
reg eth_stim_detected_packet_tx; |
|
// If in call-response mode, whenever we receive a TX packet, we generate |
// one and send it back |
always @(negedge eth_stim_detected_packet_tx) |
begin |
if (eth_stim_do_rx_reponse_to_tx & ethmac_rxen) |
// Continue if we are enabled |
do_rx_response_to_tx(); |
end |
|
|
// If in call-response mode, whenever we receive a TX packet, we generate |
// one and send it back |
always @(posedge eth_stim_do_overflow_test) |
begin |
// Continue if we are enabled |
do_overflow_stimulus(); |
end |
|
// Generate RX packet in rsponse to TX packet |
task do_rx_response_to_tx; |
//input unused; |
|
reg [31:0] IPG; // Inter-packet gap |
reg [31:0] packet_size; |
|
integer j; |
begin |
|
// Get packet size test wants us to send |
packet_size = {eth_phy0.tx_mem[0],eth_phy0.tx_mem[1], |
eth_phy0.tx_mem[2],eth_phy0.tx_mem[3]}; |
|
|
IPG = {eth_phy0.tx_mem[4],eth_phy0.tx_mem[5], |
eth_phy0.tx_mem[6],eth_phy0.tx_mem[7]}; |
|
|
$display("do_rx_response_to_tx IPG = %0d", IPG); |
if (packet_size == 0) |
begin |
// Constrained random sized packets |
packet_size = $random; |
|
while (packet_size > (max_eth_packet_size-4)) |
packet_size = packet_size / 2; |
|
if (packet_size < 60) |
packet_size = packet_size + 60; |
end |
|
$display("do_rx_response_to_tx packet_size = %0d", packet_size); |
send_packet_loop(1, packet_size, 2'b01, 1, eth_phy0.eth_speed, |
IPG, 48'h0012_3456_789a, |
48'h0708_090A_0B0C, 1, 1'b0, 0, 0); |
|
// If RX enable went low, wait for it go high again |
if (ethmac_rxen===1'b0) |
begin |
|
while (ethmac_rxen===1'b0) |
begin |
@(posedge ethmac_rxen); |
#10000; |
end |
|
// RX disabled and when re-enabled we reset the buffer |
// descriptor number |
expected_rxbd = num_tx_bds; |
|
end |
|
end |
endtask // do_rx_response_to_tx |
|
// Generate RX packet in rsponse to TX packet |
task do_overflow_stimulus; |
//input unused; |
reg [31:0] IPG; // Inter-packet gap |
reg [31:0] packet_size; |
|
integer j; |
|
begin |
|
// Maximum packet size |
packet_size = 1500; |
|
// Minimum IPG |
IPG = eth_stim_IPG_min_100mb; |
|
$display("do_overflow_stimulus IPG = %0d", IPG); |
|
|
$display("do_overflow_stimulus packetsize = %0d", packet_size); |
|
send_packet_loop(num_rx_bds, packet_size, 2'b01, 1, |
eth_phy0.eth_speed, |
IPG, 48'h0012_3456_789a, |
48'h0708_090A_0B0C, 1, 1'b0, 0, 0); |
|
// This one should cause overflow, don't check it gets there OK |
send_packet_loop(1, packet_size, 2'b01, 1, |
eth_phy0.eth_speed, |
IPG, 48'h0012_3456_789a, |
48'h0708_090A_0B0C, 1, 1'b0, 0, 1); |
|
// Wind back expected RXBD number |
if (expected_rxbd == num_tx_bds) |
expected_rxbd = num_tx_bds + num_rx_bds - 1; |
else |
expected_rxbd = expected_rxbd - 1; |
|
// This one should cause overflow, don't check it gets there OK |
send_packet_loop(1, packet_size, 2'b01, 1, |
eth_phy0.eth_speed, |
IPG, 48'h0012_3456_789a, |
48'h0708_090A_0B0C, 1, 1'b0, 0, 1); |
|
// Wind back expected RXBD number |
if (expected_rxbd == num_tx_bds) |
expected_rxbd = num_tx_bds + num_rx_bds - 1; |
else |
expected_rxbd = expected_rxbd - 1; |
|
|
// This one should cause overflow, don't check it gets there OK |
send_packet_loop(1, packet_size, 2'b01, 1, |
eth_phy0.eth_speed, |
IPG, 48'h0012_3456_789a, |
48'h0708_090A_0B0C, 1, 1'b0, 0, 1); |
|
// Wind back expected RXBD number |
if (expected_rxbd == num_tx_bds) |
expected_rxbd = num_tx_bds + num_rx_bds - 1; |
else |
expected_rxbd = expected_rxbd - 1; |
|
|
// This one should cause overflow, don't check it gets there OK |
send_packet_loop(1, packet_size, 2'b01, 1, |
eth_phy0.eth_speed, |
IPG, 48'h0012_3456_789a, |
48'h0708_090A_0B0C, 1, 1'b0, 0, 1); |
|
// Wind back expected RXBD number |
if (expected_rxbd == num_tx_bds) |
expected_rxbd = num_tx_bds + num_rx_bds - 1; |
else |
expected_rxbd = expected_rxbd - 1; |
|
|
// Wait until a buffer descriptor becomes available |
while(`ETH_TOP.wishbone.RxBDRead==1'b1) |
#1000; |
|
$display("%t: RxBDRead gone low",$time); |
#10000; |
|
|
|
send_packet_loop(1, packet_size, 2'b01, 1, eth_phy0.eth_speed, |
IPG, 48'h0012_3456_789a, |
48'h0708_090A_0B0C, 1, 1'b0, 0, 0); |
|
|
// If RX enable went low, wait for it go high again |
if (ethmac_rxen===1'b0) |
begin |
|
while (ethmac_rxen===1'b0) |
begin |
@(posedge ethmac_rxen); |
#10000; |
end |
|
// RX disabled and when re-enabled we reset the buffer |
// descriptor number |
expected_rxbd = num_tx_bds; |
|
end |
|
end |
endtask // do_overflow_stimulus |
|
|
// |
// always@() to check the TX buffer descriptors |
// |
always @(posedge ethmac_txen) |
begin |
ethmac_last_txbd_lenstat = 0; |
eth_stim_tx_loop_keep_polling=1; |
// Wait on the TxBD Ready bit |
while(eth_stim_tx_loop_keep_polling) |
begin |
#10; |
get_bd_lenstat(expected_txbd, ethmac_txbd_lenstat); |
// Check if we've finished transmitting this BD |
if (!ethmac_txbd_lenstat[15] & ethmac_last_txbd_lenstat[15]) |
// Falling edge of TX BD Ready |
eth_stim_detected_packet_tx = 1; |
|
ethmac_last_txbd_lenstat = ethmac_txbd_lenstat; |
|
// If TX en goes low then exit |
if (!ethmac_txen) |
eth_stim_tx_loop_keep_polling = 0; |
else if (eth_stim_detected_packet_tx) |
begin |
// Wait until the eth_phy has finished receiving it |
while (eth_phy0.mtxen_i === 1'b1) |
#10; |
|
$display("(%t) Check TX packet: bd %d: 0x%h",$time, |
expected_txbd, ethmac_txbd_lenstat); |
|
// Check the TXBD, see if the packet transmitted OK |
if (ethmac_txbd_lenstat[8] | ethmac_txbd_lenstat[3]) |
begin |
// Error occured |
`TIME; |
$display("*E TX Error of packet %0d detected.", |
num_tx_packets); |
$display(" TX BD %0d = 0x%h", expected_txbd, |
ethmac_txbd_lenstat); |
if (ethmac_txbd_lenstat[8]) |
$display(" Underrun in MAC during TX"); |
if (ethmac_txbd_lenstat[3]) |
$display(" Retransmission limit hit"); |
|
$finish; |
end |
else |
begin |
// Packet was OK, let's compare the contents we |
// received with those that were meant to be transmitted |
if (eth_stim_check_tx_packet_contents) |
begin |
check_tx_packet(expected_txbd); |
expected_txbd = (expected_txbd + 1) & |
num_tx_bds_mask; |
num_tx_packets = num_tx_packets + 1; |
eth_stim_detected_packet_tx = 0; |
end |
end |
end |
end // while (eth_stim_tx_loop_keep_polling) |
end // always @ (posedge ethmac_txen) |
|
|
|
|
`ifdef XILINX_DDR2 |
// Gets word from correct bank |
task get_32bitword_from_xilinx_ddr2; |
input [31:0] addr; |
output [31:0] insn; |
reg [16*8-1:0] ddr2_array_line0,ddr2_array_line1,ddr2_array_line2, |
ddr2_array_line3; |
integer word_in_line_num; |
begin |
// Get our 4 128-bit chunks (8 half-words in each!! Confused yet?), |
// 16 words total |
gen_cs[0].gen[0].u_mem0.memory_read(addr[28:27],addr[26:13], |
{addr[12:6],3'd0}, |
ddr2_array_line0); |
gen_cs[0].gen[1].u_mem0.memory_read(addr[28:27],addr[26:13], |
{addr[12:6],3'd0}, |
ddr2_array_line1); |
gen_cs[0].gen[2].u_mem0.memory_read(addr[28:27],addr[26:13], |
{addr[12:6],3'd0}, |
ddr2_array_line2); |
gen_cs[0].gen[3].u_mem0.memory_read(addr[28:27],addr[26:13], |
{addr[12:6],3'd0}, |
ddr2_array_line3); |
case (addr[5:2]) |
4'h0: |
begin |
insn[15:0] = ddr2_array_line0[15:0]; |
insn[31:16] = ddr2_array_line1[15:0]; |
end |
4'h1: |
begin |
insn[15:0] = ddr2_array_line2[15:0]; |
insn[31:16] = ddr2_array_line3[15:0]; |
end |
4'h2: |
begin |
insn[15:0] = ddr2_array_line0[31:16]; |
insn[31:16] = ddr2_array_line1[31:16]; |
end |
4'h3: |
begin |
insn[15:0] = ddr2_array_line2[31:16]; |
insn[31:16] = ddr2_array_line3[31:16]; |
end |
4'h4: |
begin |
insn[15:0] = ddr2_array_line0[47:32]; |
insn[31:16] = ddr2_array_line1[47:32]; |
end |
4'h5: |
begin |
insn[15:0] = ddr2_array_line2[47:32]; |
insn[31:16] = ddr2_array_line3[47:32]; |
end |
4'h6: |
begin |
insn[15:0] = ddr2_array_line0[63:48]; |
insn[31:16] = ddr2_array_line1[63:48]; |
end |
4'h7: |
begin |
insn[15:0] = ddr2_array_line2[63:48]; |
insn[31:16] = ddr2_array_line3[63:48]; |
end |
4'h8: |
begin |
insn[15:0] = ddr2_array_line0[79:64]; |
insn[31:16] = ddr2_array_line1[79:64]; |
end |
4'h9: |
begin |
insn[15:0] = ddr2_array_line2[79:64]; |
insn[31:16] = ddr2_array_line3[79:64]; |
end |
4'ha: |
begin |
insn[15:0] = ddr2_array_line0[95:80]; |
insn[31:16] = ddr2_array_line1[95:80]; |
end |
4'hb: |
begin |
insn[15:0] = ddr2_array_line2[95:80]; |
insn[31:16] = ddr2_array_line3[95:80]; |
end |
4'hc: |
begin |
insn[15:0] = ddr2_array_line0[111:96]; |
insn[31:16] = ddr2_array_line1[111:96]; |
end |
4'hd: |
begin |
insn[15:0] = ddr2_array_line2[111:96]; |
insn[31:16] = ddr2_array_line3[111:96]; |
end |
4'he: |
begin |
insn[15:0] = ddr2_array_line0[127:112]; |
insn[31:16] = ddr2_array_line1[127:112]; |
end |
4'hf: |
begin |
insn[15:0] = ddr2_array_line2[127:112]; |
insn[31:16] = ddr2_array_line3[127:112]; |
end |
endcase // case (addr[5:2]) |
end |
endtask |
|
task get_byte_from_xilinx_ddr2; |
input [31:0] addr; |
output [7:0] data_byte; |
reg [31:0] word; |
begin |
get_32bitword_from_xilinx_ddr2(addr, word); |
case (addr[1:0]) |
2'b00: |
data_byte = word[31:24]; |
2'b01: |
data_byte = word[23:16]; |
2'b10: |
data_byte = word[15:8]; |
2'b11: |
data_byte = word[7:0]; |
endcase // case (addr[1:0]) |
end |
endtask // get_byte_from_xilinx_ddr2 |
|
`endif |
|
`ifdef XILINX_DDR2 |
task sync_controller_cache_xilinx_ddr; |
begin |
// Sync cache (writeback dirty lines) with external memory |
dut.xilinx_ddr2_0.xilinx_ddr2_if0.do_sync; |
// Wait for it to occur. |
while (dut.xilinx_ddr2_0.xilinx_ddr2_if0.sync) |
#100; |
|
// Wait just incase writeback of all data hasn't fully occurred. |
// 4uS, in case RAM needs to refresh while writing back. |
#4_000_000; |
|
|
end |
endtask // sync_controller_cache_xilinx_ddr |
`endif |
|
|
// |
// Check packet TX'd by MAC was good |
// |
task check_tx_packet; |
input [31:0] tx_bd_num; |
|
reg [31:0] tx_bd_addr; |
reg [7:0] phy_byte; |
|
reg [31:0] txpnt_wb; // Pointer in array to where data should be |
reg [24:0] txpnt_sdram; // Index in array of shorts for data in SDRAM |
// part |
reg [21:0] buffer; |
reg [7:0] sdram_byte; |
reg [31:0] tx_len_bd; |
|
integer i; |
integer failure; |
begin |
failure = 0; |
|
get_bd_lenstat(tx_bd_num, tx_len_bd); |
|
tx_len_bd = {15'd0,tx_len_bd[31:16]}; |
|
// Check, if length didn't have to be padded, that |
// amount transmitted was correct |
if ((tx_len_bd > 60)&(tx_len_bd != (eth_phy0.tx_len-4))) |
begin |
$display("*E TX packet sent length, %0d != length in TX BD, %0d", |
eth_phy0.tx_len-4, tx_len_bd); |
#100; |
$finish; |
end |
|
`ifdef XILINX_DDR2 |
sync_controller_cache_xilinx_ddr; |
`endif |
|
get_bd_addr(tx_bd_num, tx_bd_addr); |
|
// We're never going to be using more than about 256K of receive buffer |
// so let's lop off the top bit of the address pointer - we only want |
// the offset from the base of the memory bank |
txpnt_wb = {14'd0,tx_bd_addr[17:0]}; |
txpnt_sdram = tx_bd_addr[24:0]; |
|
// Variable we'll use for index in the PHY's TX buffer |
buffer = 0; // Start of TX data |
|
for (i=0;i<tx_len_bd;i=i+1) |
begin |
//$display("Checking address in tx bd 0x%0h",txpnt_sdram); |
sdram_byte = 8'hx; |
`ifdef RAM_WB |
sdram_byte = dut.ram_wb0.ram_wb_b3_0.get_mem8(txpnt_sdram); |
`else |
`ifdef VERSATILE_SDRAM |
sdram0.get_byte(txpnt_sdram,sdram_byte); |
`else |
`ifdef XILINX_DDR2 |
get_byte_from_xilinx_ddr2(txpnt_sdram, sdram_byte); |
`else |
$display(" * Error: sdram_byte was %x", sdram_byte); |
|
$display(" * eth_stim needs to be able to access the main memory to check packet rx/tx"); |
$finish; |
|
`endif |
`endif |
`endif |
|
phy_byte = eth_phy0.tx_mem[buffer]; |
// Debugging output |
//$display("txpnt_sdram = 0x%h, sdram_byte = 0x%h, buffer = 0x%h, phy_byte = 0x%h", txpnt_sdram, sdram_byte, buffer, phy_byte); |
|
if (phy_byte !== sdram_byte) |
begin |
`TIME; |
$display("*E Wrong byte (%d) of TX packet! ram = %h, phy = %h",buffer, sdram_byte, phy_byte); |
failure = 1; |
end |
|
buffer = buffer + 1; |
|
txpnt_sdram = txpnt_sdram+1; |
|
end // for (i=0;i<tx_len_bd;i=i+1) |
|
if (failure) |
begin |
#100 |
`TIME; |
$display("*E Error transmitting packet %0d (%0d bytes). Finishing simulation", num_tx_packets, tx_len_bd); |
get_bd_lenstat(tx_bd_num, tx_len_bd); |
$display(" TXBD lenstat: 0x%0h",tx_len_bd); |
$display(" TXBD address: 0x%0h",tx_bd_addr); |
$finish; |
end |
else |
begin |
#1 $display( "(%0t)(%m) TX packet %0d: %0d bytes in memory OK!",$time,num_tx_packets, tx_len_bd); |
|
end |
|
|
end |
endtask // check_tx_packet |
|
|
// Local buffer of "sent" data to the ethernet MAC, we will check against |
// Size of our local buffer in bytes |
parameter eth_rx_sent_circbuf_size = (16*1024); |
parameter eth_rx_sent_circbuf_size_mask = eth_rx_sent_circbuf_size - 1; |
integer eth_rx_sent_circbuf_fill_ptr = 0; |
integer eth_rx_sent_circbuf_read_ptr = 0; |
// The actual buffer |
reg [7:0] eth_rx_sent_circbuf [0:eth_rx_sent_circbuf_size-1]; |
|
|
// |
// Task to send a set of packets |
// |
task send_packet_loop; |
input [31:0] num_packets; |
input [31:0] length; |
input [1:0] length_change; // 0 = none, 1 = incr, 2 = decrement |
input [31:0] length_change_size; // Size to change by |
input speed; |
input [31:0] back_to_back_delay; // #delay setting between packets |
input [47:0] dst_mac; |
input [47:0] src_mac; |
input random_fill; |
input random_errors; |
input [31:0] random_error_mod; |
input dont_confirm_rx; |
integer j, k; |
reg error_this_time; |
integer error_type; // 0 = rxerr, 1=bad preamble 2=bad crc 3=TODO |
reg [31:0] rx_bd_lenstat; |
begin |
error_type = 0; |
error_this_time = 0; |
|
if (num_packets == 0) |
// Loop forever when num_packets is 0 |
num_packets = 32'h7fffffff; |
|
|
if (speed & !(eth_phy0.control_bit14_10[13] === 1'b1)) |
begin |
// write to phy's control register for 100Mbps |
eth_phy0.control_bit14_10 = 5'b01000; // bit 13 set - speed 100 |
// Swapping speeds, give some delay |
#10000; |
end |
else if (!speed & !(eth_phy0.control_bit14_10[13] === 1'b0)) |
begin |
eth_phy0.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10 |
// Swapping speeds, give some delay |
#10000; |
end |
|
eth_phy0.control_bit8_0 = 9'h1_00; |
|
for(j=0;j<num_packets | length <32;j=j+1) |
begin |
eth_stim_rx_packet_length = length[15:0]; // Bytes |
st_data = 8'h0F; |
|
// setup RX packet in buffer - length is without CRC |
set_rx_packet(0, eth_stim_rx_packet_length, 1'b0, dst_mac, |
src_mac, 16'h0D0E, st_data, random_fill); |
|
set_rx_addr_type(0, dst_mac, src_mac, 16'h0D0E); |
|
// Error type 2 is cause CRC error |
append_rx_crc(0, eth_stim_rx_packet_length, 1'b0, |
(error_type==2)); |
|
if (error_this_time) |
begin |
if (error_type == 0) |
// RX ERR assert during transmit |
eth_phy0.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, |
8'hD5, 0, |
eth_stim_rx_packet_length+4, |
1'b0, 1'b1); |
else if (error_type == 1) |
// Incorrect preamble |
eth_phy0.send_rx_packet(64'h0055_5f55_5555_5555, 4'h7, |
8'hD5, 0, |
eth_stim_rx_packet_length+4, |
1'b0, 1'b0); |
else |
// Normal datapacket |
eth_phy0.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, |
8'hD5, 0, |
eth_stim_rx_packet_length+4, |
1'b0, 1'b0); |
end |
else |
eth_phy0.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, |
0, eth_stim_rx_packet_length+4, 1'b0, |
1'b0); |
|
|
// if RX enable still set (might have gone low during this packet |
if (ethmac_rxen) |
begin |
if (error_this_time || dont_confirm_rx) begin |
// Put in dummy length, checking function will skip... |
rx_packet_lengths[(eth_rx_num_packets_sent& 12'h3ff)]=32'heeeeeeee; |
|
for(k=0;k<length;k=k+1) |
// skip data in verify buffer |
eth_rx_sent_circbuf_read_ptr = (eth_rx_sent_circbuf_read_ptr+1)& |
eth_rx_sent_circbuf_size_mask; |
|
end |
else |
rx_packet_lengths[(eth_rx_num_packets_sent & 12'h3ff)] = length; |
|
eth_rx_num_packets_sent = eth_rx_num_packets_sent + 1; |
|
end // if (ethmac_rxen) |
else |
begin |
// Force the loop to finish up |
j = num_packets; |
end |
|
|
// Inter-packet gap |
#back_to_back_delay; |
|
// Update length |
if (length_change == 2'b01) |
length = length + length_change_size; |
|
if ((length_change == 2'b10) && |
((length - length_change_size) > 32)) |
length = length - length_change_size; |
|
// Increment error type |
if (error_this_time) |
error_type = error_type + 1; |
if (error_type > 3) |
error_type = 0; |
|
|
// Check if we should put in an error this time |
if (j%random_error_mod == 0) |
error_this_time = 1; |
else |
error_this_time = 0; |
|
eth_phy0.rx_err(0); |
|
// Now wait to check if we have filled up all the RX BDs and |
// the this packet would start writing over them. Only really an |
// issue when doing minimum IPG tests. |
while(((eth_rx_num_packets_sent+1) - eth_rx_num_packets_checked) |
== num_rx_bds) |
#100; |
|
|
end // for (j=0;j<num_packets | length <32;j=j+1) |
end |
endtask // send_packet_loop |
|
/* |
TASKS for set and check RX packets: |
----------------------------------- |
set_rx_packet |
(rxpnt[31:0], len[15:0], plus_nibble, d_addr[47:0], s_addr[47:0], type_len[15:0], start_data[7:0]); |
check_rx_packet |
(rxpnt_phy[31:0], rxpnt_wb[31:0], len[15:0], plus_nibble, successful_nibble, failure[31:0]); |
*/ |
task set_rx_packet; |
input [31:0] rxpnt; // pointer to place in in the phy rx buffer we'll start at |
input [15:0] len; |
input plus_dribble_nibble; // if length is longer for one nibble |
input [47:0] eth_dest_addr; |
input [47:0] eth_source_addr; |
input [15:0] eth_type_len; |
input [7:0] eth_start_data; |
input random_fill; |
integer i, sd; |
reg [47:0] dest_addr; |
reg [47:0] source_addr; |
reg [15:0] type_len; |
reg [21:0] buffer; |
reg delta_t; |
|
begin |
buffer = rxpnt[21:0]; |
dest_addr = eth_dest_addr; |
source_addr = eth_source_addr; |
type_len = eth_type_len; |
sd = eth_start_data; |
delta_t = 0; |
for(i = 0; i < len; i = i + 1) |
begin |
if (i < 6) |
begin |
eth_phy0.rx_mem[buffer] = dest_addr[47:40]; |
dest_addr = dest_addr << 8; |
end |
else if (i < 12) |
begin |
eth_phy0.rx_mem[buffer] = source_addr[47:40]; |
source_addr = source_addr << 8; |
end |
else if (i < 14) |
begin |
eth_phy0.rx_mem[buffer] = type_len[15:8]; |
type_len = type_len << 8; |
end |
else |
begin |
if (random_fill) |
begin |
if (lfsr_last_byte == 0) |
eth_phy0.rx_mem[buffer] = lfsr[15:8]; |
if (lfsr_last_byte == 1) |
eth_phy0.rx_mem[buffer] = lfsr[23:16]; |
if (lfsr_last_byte == 2) |
eth_phy0.rx_mem[buffer] = lfsr[31:24]; |
if (lfsr_last_byte == 3) |
begin |
eth_phy0.rx_mem[buffer] = lfsr[7:0]; |
lfsr = {lfsr[30:0],(((lfsr[31] ^ lfsr[6]) ^ |
lfsr[5]) ^ lfsr[1])}; |
lfsr_last_byte = 0; |
end |
else |
lfsr_last_byte = lfsr_last_byte + 1; |
|
end // if (random_fill) |
else |
eth_phy0.rx_mem[buffer] = sd[7:0]; |
sd = sd + 1; |
end // else: !if(i < 14) |
|
// Update our local buffer |
eth_rx_sent_circbuf[eth_rx_sent_circbuf_fill_ptr] |
= eth_phy0.rx_mem[buffer]; |
eth_rx_sent_circbuf_fill_ptr = (eth_rx_sent_circbuf_fill_ptr+1)& |
eth_rx_sent_circbuf_size_mask; |
|
buffer = buffer + 1; |
end // for (i = 0; i < len; i = i + 1) |
|
delta_t = !delta_t; |
if (plus_dribble_nibble) |
eth_phy0.rx_mem[buffer] = {4'h0, 4'hD /*sd[3:0]*/}; |
delta_t = !delta_t; |
end |
endtask // set_rx_packet |
|
|
|
|
task set_rx_addr_type; |
input [31:0] rxpnt; |
input [47:0] eth_dest_addr; |
input [47:0] eth_source_addr; |
input [15:0] eth_type_len; |
integer i; |
reg [47:0] dest_addr; |
reg [47:0] source_addr; |
reg [15:0] type_len; |
reg [21:0] buffer; |
reg delta_t; |
begin |
buffer = rxpnt[21:0]; |
dest_addr = eth_dest_addr; |
source_addr = eth_source_addr; |
type_len = eth_type_len; |
delta_t = 0; |
for(i = 0; i < 14; i = i + 1) |
begin |
if (i < 6) |
begin |
eth_phy0.rx_mem[buffer] = dest_addr[47:40]; |
dest_addr = dest_addr << 8; |
end |
else if (i < 12) |
begin |
eth_phy0.rx_mem[buffer] = source_addr[47:40]; |
source_addr = source_addr << 8; |
end |
else // if (i < 14) |
begin |
eth_phy0.rx_mem[buffer] = type_len[15:8]; |
type_len = type_len << 8; |
end |
buffer = buffer + 1; |
end |
delta_t = !delta_t; |
end |
endtask // set_rx_addr_type |
|
|
// Check if we're using a synthesized version of eth module |
`ifdef ethmac_IS_GATELEVEL |
|
// Get the length/status register of the ethernet buffer descriptor |
task get_bd_lenstat; |
input [31:0] bd_num;// Number of ethernet BD to check |
output [31:0] bd_lenstat; |
`ifdef ACTEL |
reg [8:0] tmp; |
integer raddr; |
`endif |
begin |
`ifdef ACTEL |
|
// Pull from the Actel memory model |
raddr = `ETH_BD_RAM_PATH.\mem_tile.I_1 .get_address((bd_num*2)); |
|
tmp = `ETH_BD_RAM_PATH.\mem_tile.I_1 .MEM_512_9[(raddr*2)]; |
bd_lenstat[8:0] = tmp[8:0]; |
|
tmp = `ETH_BD_RAM_PATH.\mem_tile.I_1 .MEM_512_9[(raddr*2)+1]; |
bd_lenstat[17:9] = tmp[8:0]; |
|
raddr = `ETH_BD_RAM_PATH.\mem_tile_0.I_1 .get_address((bd_num*2)); |
|
tmp = `ETH_BD_RAM_PATH.\mem_tile_0.I_1 .MEM_512_9[(raddr*2)]; |
bd_lenstat[26:18] = tmp[8:0]; |
|
tmp = `ETH_BD_RAM_PATH.\mem_tile_0.I_1 .MEM_512_9[(raddr*2)+1]; |
bd_lenstat[31:27] = tmp[4:0]; |
|
//$display("(%t) read eth bd lenstat %h",$time, bd_lenstat); |
`endif |
end |
endtask // get_bd_lenstat |
|
// Get the length/status register of the ethernet buffer descriptor |
task get_bd_addr; |
input [31:0] bd_num;// Number of the ethernet BD to check |
output [31:0] bd_addr; |
`ifdef ACTEL |
reg [8:0] tmp; |
integer raddr; |
`endif |
begin |
`ifdef ACTEL |
// Pull from the Actel memory model |
raddr = `ETH_BD_RAM_PATH.\mem_tile.I_1 .get_address((bd_num*2)+1); |
|
tmp = `ETH_BD_RAM_PATH.\mem_tile.I_1 .MEM_512_9[(raddr*2)]; |
bd_addr[8:0] = tmp[8:0]; |
|
tmp = `ETH_BD_RAM_PATH.\mem_tile.I_1 .MEM_512_9[(raddr*2)+1]; |
bd_addr[17:9] = tmp[8:0]; |
|
raddr = `ETH_BD_RAM_PATH.\mem_tile_0.I_1 .get_address((bd_num*2)+1); |
|
tmp = `ETH_BD_RAM_PATH.\mem_tile_0.I_1 .MEM_512_9[(raddr*2)]; |
bd_addr[26:18] = tmp[8:0]; |
|
tmp = `ETH_BD_RAM_PATH.\mem_tile_0.I_1 .MEM_512_9[(raddr*2)+1]; |
bd_addr[31:27] = tmp[4:0]; |
|
//$display("(%t) read eth bd%d addr %h",$time,bd_num, bd_addr); |
`endif |
end |
endtask // get_bd_addr |
|
`else // !`ifdef ethmac_IS_GATELEVEL |
|
// Get the length/status register of the ethernet buffer descriptor |
task get_bd_lenstat; |
input [31:0] bd_num;// Number of ethernet BD to check |
output [31:0] bd_lenstat; |
begin |
bd_lenstat = `ETH_BD_RAM_PATH.mem[(bd_num*2)]; |
end |
endtask // get_bd_lenstat |
|
// Get the length/status register of the ethernet buffer descriptor |
task get_bd_addr; |
input [31:0] bd_num;// Number of the ethernet BD to check |
output [31:0] bd_addr; |
begin |
bd_addr = `ETH_BD_RAM_PATH.mem[((bd_num*2)+1)]; |
//$display("(%t) read eth bd%d addr %h",$time,bd_num, bd_addr); |
end |
endtask // get_bd_addr |
`endif |
|
// Always block triggered by finishing of transmission of new packet from |
// send_packet_loop |
integer eth_rx_packet_length_to_check; |
|
always @* |
begin |
// Loop here until: |
// 1 - packets sent is not equal to packets checked (ie. some to check) |
// 2 - we're explicitly disabled for some reason |
// 3 - Receive has been disabled in the MAC |
while((eth_rx_num_packets_sent == eth_rx_num_packets_checked) || |
!eth_stim_check_rx_packet_contents || !(ethmac_rxen===1'b1)) |
#1000; |
|
eth_rx_packet_length_to_check |
= rx_packet_lengths[(eth_rx_num_packets_checked & 12'h3ff)]; |
|
if ( eth_rx_packet_length_to_check !== 32'heeeeeeee) |
check_rx_packet(expected_rxbd, 0, eth_rx_packet_length_to_check); |
|
eth_rx_num_packets_checked = eth_rx_num_packets_checked + 1; |
|
expected_rxbd = expected_rxbd + 1; |
|
// Wrap |
if (expected_rxbd == (num_tx_bds + num_rx_bds)) |
expected_rxbd = num_tx_bds; |
end |
|
task check_rx_packet; |
|
input [31:0] rx_bd_num; |
input [31:0] rxpnt_phy; // Pointer in array of data in PHY |
input [31:0] len; |
|
reg [31:0] rx_bd_lenstat; |
reg [31:0] rx_bd_addr; |
reg [7:0] phy_byte; |
|
reg [31:0] rxpnt_wb; // Pointer in array to where data should be |
reg [24:0] rxpnt_sdram; // byte address from CPU in RAM |
reg [15:0] sdram_short; |
reg [7:0] sdram_byte; |
|
integer i; |
integer failure; |
|
begin |
|
failure = 0; |
|
// Wait until the buffer descriptor indicates the packet has been |
// received... |
get_bd_lenstat(rx_bd_num, rx_bd_lenstat); |
while (rx_bd_lenstat & 32'h00008000)// Check Empty bit |
begin |
#10; |
get_bd_lenstat(rx_bd_num, rx_bd_lenstat); |
//$display("(%t) check_rx_packet: poll bd %d: 0x%h",$time, |
// rx_bd_num, rx_bd_lenstat); |
end |
|
|
// Delay some time - takes a bit for the Wishbone FSM to pipe out the |
// packet over Wishbone and into whatever memory it's going into |
#Td_rx_packet_check; |
|
`ifdef XILINX_DDR2 |
sync_controller_cache_xilinx_ddr; |
`endif |
|
// Ok, buffer filled, let's get its offset in memory |
get_bd_addr(rx_bd_num, rx_bd_addr); |
|
$display("(%t) Check RX packet: bd %d: 0x%h, addr 0x%h",$time, |
rx_bd_num, rx_bd_lenstat, rx_bd_addr); |
|
|
// We're never going to be using more than about 256KB of receive buffer |
// so let's lop off the top bit of the address pointer - we only want |
// the offset from the base of the memory bank |
|
rxpnt_wb = {14'd0,rx_bd_addr[17:0]}; |
rxpnt_sdram = rx_bd_addr[24:0]; |
|
|
//$display("RAM pointer for BD is 0x%h, SDRAM addr is 0x%h", rx_bd_addr, rxpnt_sdram); |
|
|
for (i=0;i<len;i=i+1) |
begin |
|
sdram_byte = 8'hx; |
|
`ifdef RAM_WB |
sdram_byte = dut.ram_wb0.ram_wb_b3_0.get_mem8(rxpnt_sdram); |
`else |
`ifdef XILINX_DDR2 |
get_byte_from_xilinx_ddr2(rxpnt_sdram, sdram_byte); |
`else |
$display(" * Error:"); |
|
$display(" * eth_stim needs to be able to access the main memory to check packet rx/tx"); |
$finish; |
`endif |
`endif |
|
phy_byte = eth_rx_sent_circbuf[eth_rx_sent_circbuf_read_ptr]; |
|
if (phy_byte !== sdram_byte) |
begin |
// `TIME; |
$display("*E Wrong byte (%5d) of RX packet %5d. phy mem = %h, ram = %h", |
i, eth_rx_num_packets_checked, phy_byte, sdram_byte); |
failure = 1; |
end |
|
eth_rx_sent_circbuf_read_ptr = (eth_rx_sent_circbuf_read_ptr+1)& |
eth_rx_sent_circbuf_size_mask; |
|
rxpnt_sdram = rxpnt_sdram+1; |
|
end // for (i=0;i<len;i=i+2) |
|
if (failure) |
begin |
#100 |
`TIME; |
$display("*E Recieved packet %0d, length %0d bytes, had an error. Finishing simulation.", eth_rx_num_packets_checked, len); |
$finish; |
end |
else |
begin |
#1 $display( "(%0t)(%m) RX packet %0d: %0d bytes in memory OK!",$time,eth_rx_num_packets_checked, len); |
|
end |
end |
endtask // check_rx_packet |
|
|
////////////////////////////////////////////////////////////// |
// Ethernet CRC Basic tasks |
////////////////////////////////////////////////////////////// |
|
task append_rx_crc; |
input [31:0] rxpnt_phy; // source |
input [15:0] len; // length in bytes without CRC |
input plus_dribble_nibble; // if length is longer for one nibble |
input negated_crc; // if appended CRC is correct or not |
reg [31:0] crc; |
reg [7:0] tmp; |
reg [31:0] addr_phy; |
reg delta_t; |
begin |
addr_phy = rxpnt_phy + len; |
delta_t = 0; |
// calculate CRC from prepared packet |
paralel_crc_phy_rx(rxpnt_phy, {16'h0, len}, plus_dribble_nibble, crc); |
if (negated_crc) |
crc = ~crc; |
delta_t = !delta_t; |
|
if (plus_dribble_nibble) |
begin |
tmp = eth_phy0.rx_mem[addr_phy]; |
eth_phy0.rx_mem[addr_phy] = {crc[27:24], tmp[3:0]}; |
eth_phy0.rx_mem[addr_phy + 1] = {crc[19:16], crc[31:28]}; |
eth_phy0.rx_mem[addr_phy + 2] = {crc[11:8], crc[23:20]}; |
eth_phy0.rx_mem[addr_phy + 3] = {crc[3:0], crc[15:12]}; |
eth_phy0.rx_mem[addr_phy + 4] = {4'h0, crc[7:4]}; |
end |
else |
begin |
eth_phy0.rx_mem[addr_phy] = crc[31:24]; |
eth_phy0.rx_mem[addr_phy + 1] = crc[23:16]; |
eth_phy0.rx_mem[addr_phy + 2] = crc[15:8]; |
eth_phy0.rx_mem[addr_phy + 3] = crc[7:0]; |
end |
end |
endtask // append_rx_crc |
|
task append_rx_crc_delayed; |
input [31:0] rxpnt_phy; // source |
input [15:0] len; // length in bytes without CRC |
input plus_dribble_nibble; // if length is longer for one nibble |
input negated_crc; // if appended CRC is correct or not |
reg [31:0] crc; |
reg [7:0] tmp; |
reg [31:0] addr_phy; |
reg delta_t; |
begin |
addr_phy = rxpnt_phy + len; |
delta_t = 0; |
// calculate CRC from prepared packet |
paralel_crc_phy_rx(rxpnt_phy+4, {16'h0, len}-4, plus_dribble_nibble, crc); |
if (negated_crc) |
crc = ~crc; |
delta_t = !delta_t; |
|
if (plus_dribble_nibble) |
begin |
tmp = eth_phy0.rx_mem[addr_phy]; |
eth_phy0.rx_mem[addr_phy] = {crc[27:24], tmp[3:0]}; |
eth_phy0.rx_mem[addr_phy + 1] = {crc[19:16], crc[31:28]}; |
eth_phy0.rx_mem[addr_phy + 2] = {crc[11:8], crc[23:20]}; |
eth_phy0.rx_mem[addr_phy + 3] = {crc[3:0], crc[15:12]}; |
eth_phy0.rx_mem[addr_phy + 4] = {4'h0, crc[7:4]}; |
end |
else |
begin |
eth_phy0.rx_mem[addr_phy] = crc[31:24]; |
eth_phy0.rx_mem[addr_phy + 1] = crc[23:16]; |
eth_phy0.rx_mem[addr_phy + 2] = crc[15:8]; |
eth_phy0.rx_mem[addr_phy + 3] = crc[7:0]; |
end |
end |
endtask // append_rx_crc_delayed |
|
|
// paralel CRC calculating for PHY RX |
task paralel_crc_phy_rx; |
input [31:0] start_addr; // start address |
input [31:0] len; // length of frame in Bytes without CRC length |
input plus_dribble_nibble; // if length is longer for one nibble |
output [31:0] crc_out; |
reg [21:0] addr_cnt; // only 22 address lines |
integer word_cnt; |
integer nibble_cnt; |
reg [31:0] load_reg; |
reg delta_t; |
reg [31:0] crc_next; |
reg [31:0] crc; |
reg crc_error; |
reg [3:0] data_in; |
integer i; |
begin |
#1 addr_cnt = start_addr[21:0]; |
word_cnt = 24; // 27; // start of the frame - nibble granularity (MSbit first) |
crc = 32'hFFFF_FFFF; // INITIAL value |
delta_t = 0; |
// length must include 4 bytes of ZEROs, to generate CRC |
// get number of nibbles from Byte length (2^1 = 2) |
if (plus_dribble_nibble) |
nibble_cnt = ((len + 4) << 1) + 1'b1; // one nibble longer |
else |
nibble_cnt = ((len + 4) << 1); |
// because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3] |
load_reg[31:24] = eth_phy0.rx_mem[addr_cnt]; |
addr_cnt = addr_cnt + 1; |
load_reg[23:16] = eth_phy0.rx_mem[addr_cnt]; |
addr_cnt = addr_cnt + 1; |
load_reg[15: 8] = eth_phy0.rx_mem[addr_cnt]; |
addr_cnt = addr_cnt + 1; |
load_reg[ 7: 0] = eth_phy0.rx_mem[addr_cnt]; |
addr_cnt = addr_cnt + 1; |
while (nibble_cnt > 0) |
begin |
// wait for delta time |
delta_t = !delta_t; |
// shift data in |
|
if(nibble_cnt <= 8) // for additional 8 nibbles shift ZEROs in! |
data_in[3:0] = 4'h0; |
else |
|
data_in[3:0] = {load_reg[word_cnt], load_reg[word_cnt+1], load_reg[word_cnt+2], load_reg[word_cnt+3]}; |
crc_next[0] = (data_in[0] ^ crc[28]); |
crc_next[1] = (data_in[1] ^ data_in[0] ^ crc[28] ^ crc[29]); |
crc_next[2] = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28] ^ crc[29] ^ crc[30]); |
crc_next[3] = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29] ^ crc[30] ^ crc[31]); |
crc_next[4] = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28] ^ crc[30] ^ crc[31]) ^ crc[0]; |
crc_next[5] = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28] ^ crc[29] ^ crc[31]) ^ crc[1]; |
crc_next[6] = (data_in[2] ^ data_in[1] ^ crc[29] ^ crc[30]) ^ crc[ 2]; |
crc_next[7] = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28] ^ crc[30] ^ crc[31]) ^ crc[3]; |
crc_next[8] = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28] ^ crc[29] ^ crc[31]) ^ crc[4]; |
crc_next[9] = (data_in[2] ^ data_in[1] ^ crc[29] ^ crc[30]) ^ crc[5]; |
crc_next[10] = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28] ^ crc[30] ^ crc[31]) ^ crc[6]; |
crc_next[11] = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28] ^ crc[29] ^ crc[31]) ^ crc[7]; |
crc_next[12] = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28] ^ crc[29] ^ crc[30]) ^ crc[8]; |
crc_next[13] = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29] ^ crc[30] ^ crc[31]) ^ crc[9]; |
crc_next[14] = (data_in[3] ^ data_in[2] ^ crc[30] ^ crc[31]) ^ crc[10]; |
crc_next[15] = (data_in[3] ^ crc[31]) ^ crc[11]; |
crc_next[16] = (data_in[0] ^ crc[28]) ^ crc[12]; |
crc_next[17] = (data_in[1] ^ crc[29]) ^ crc[13]; |
crc_next[18] = (data_in[2] ^ crc[30]) ^ crc[14]; |
crc_next[19] = (data_in[3] ^ crc[31]) ^ crc[15]; |
crc_next[20] = crc[16]; |
crc_next[21] = crc[17]; |
crc_next[22] = (data_in[0] ^ crc[28]) ^ crc[18]; |
crc_next[23] = (data_in[1] ^ data_in[0] ^ crc[29] ^ crc[28]) ^ crc[19]; |
crc_next[24] = (data_in[2] ^ data_in[1] ^ crc[30] ^ crc[29]) ^ crc[20]; |
crc_next[25] = (data_in[3] ^ data_in[2] ^ crc[31] ^ crc[30]) ^ crc[21]; |
crc_next[26] = (data_in[3] ^ data_in[0] ^ crc[31] ^ crc[28]) ^ crc[22]; |
crc_next[27] = (data_in[1] ^ crc[29]) ^ crc[23]; |
crc_next[28] = (data_in[2] ^ crc[30]) ^ crc[24]; |
crc_next[29] = (data_in[3] ^ crc[31]) ^ crc[25]; |
crc_next[30] = crc[26]; |
crc_next[31] = crc[27]; |
|
crc = crc_next; |
crc_error = crc[31:0] != 32'hc704dd7b; // CRC not equal to magic number |
case (nibble_cnt) |
9: crc_out = {!crc[24], !crc[25], !crc[26], !crc[27], !crc[28], !crc[29], !crc[30], !crc[31], |
!crc[16], !crc[17], !crc[18], !crc[19], !crc[20], !crc[21], !crc[22], !crc[23], |
!crc[ 8], !crc[ 9], !crc[10], !crc[11], !crc[12], !crc[13], !crc[14], !crc[15], |
!crc[ 0], !crc[ 1], !crc[ 2], !crc[ 3], !crc[ 4], !crc[ 5], !crc[ 6], !crc[ 7]}; |
default: crc_out = crc_out; |
endcase |
// wait for delta time |
delta_t = !delta_t; |
// increment address and load new data |
if ((word_cnt+3) == 7)//4) |
begin |
// because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3] |
load_reg[31:24] = eth_phy0.rx_mem[addr_cnt]; |
addr_cnt = addr_cnt + 1; |
load_reg[23:16] = eth_phy0.rx_mem[addr_cnt]; |
addr_cnt = addr_cnt + 1; |
load_reg[15: 8] = eth_phy0.rx_mem[addr_cnt]; |
addr_cnt = addr_cnt + 1; |
load_reg[ 7: 0] = eth_phy0.rx_mem[addr_cnt]; |
addr_cnt = addr_cnt + 1; |
end |
// set new load bit position |
if((word_cnt+3) == 31) |
word_cnt = 16; |
else if ((word_cnt+3) == 23) |
word_cnt = 8; |
else if ((word_cnt+3) == 15) |
word_cnt = 0; |
else if ((word_cnt+3) == 7) |
word_cnt = 24; |
else |
word_cnt = word_cnt + 4;// - 4; |
// decrement nibble counter |
nibble_cnt = nibble_cnt - 1; |
// wait for delta time |
delta_t = !delta_t; |
end // while |
#1; |
end |
endtask // paralel_crc_phy_rx |
|
|
|
|
/s3adsp1800/bench/verilog/include/eth_phy_defines.v
0,0 → 1,91
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name: eth_phy_defines.v //// |
//// //// |
//// This file is part of the Ethernet IP core project //// |
//// http://www.opencores.org/projects/ethmac/ //// |
//// //// |
//// Author(s): //// |
//// - Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// All additional information is available in the README.txt //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2002, Authors //// |
//// //// |
//// 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 $ |
// Revision 1.1 2002/09/13 11:57:20 mohor |
// New testbench. Thanks to Tadej M - "The Spammer". |
// |
// |
// |
|
// Address of PHY device (LXT971A) |
`define ETH_PHY_ADDR 5'h00 //Changed to 0 -jb |
|
// LED/Configuration pins on PHY device - see the specification, page 26, table 8 |
// Initial set of bits 13, 12 and 8 of Control Register |
`define LED_CFG1 1'b0 |
`define LED_CFG2 1'b1 |
`define LED_CFG3 1'b1 |
|
|
// Supported speeds and physical ports - see the specification, page 67, table 41 |
// Set bits 15 to 9 of Status Register |
`define SUPPORTED_SPEED_AND_PORT 7'h3F |
|
// Extended status register (address 15) |
// Set bit 8 of Status Register |
`define EXTENDED_STATUS 1'b0 |
|
// Default status bits - see the specification, page 67, table 41 |
// Set bits 6 to 0 of Status Register |
`define DEFAULT_STATUS 7'h09 |
|
// PHY ID 1 number - see the specification, page 68, table 42 |
// Set bits of Phy Id Register 1 |
`define PHY_ID1 16'h0013 |
|
// PHY ID 2 number - see the specification, page 68, table 43 |
// Set bits 15 to 10 of Phy Id Register 2 |
`define PHY_ID2 6'h1E |
|
// Manufacturer MODEL number - see the specification, page 68, table 43 |
// Set bits 9 to 4 of Phy Id Register 2 |
`define MAN_MODEL_NUM 6'h0E |
|
// Manufacturer REVISION number - see the specification, page 68, table 43 |
// Set bits 3 to 0 of Phy Id Register 2 |
`define MAN_REVISION_NUM 4'h2 |
|
|
|
|
/s3adsp1800/bench/verilog/include/ddr2_model_parameters.v
0,0 → 1,391
/**************************************************************************************** |
* |
* Disclaimer This software code and all associated documentation, comments or other |
* of Warranty: information (collectively "Software") is provided "AS IS" without |
* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY |
* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED |
* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES |
* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT |
* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE |
* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE. |
* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR |
* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS, |
* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE |
* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI, |
* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT, |
* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING, |
* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION, |
* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE |
* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
* DAMAGES. Because some jurisdictions prohibit the exclusion or |
* limitation of liability for consequential or incidental damages, the |
* above limitation may not apply to you. |
* |
* Copyright 2003 Micron Technology, Inc. All rights reserved. |
* |
****************************************************************************************/ |
|
// Parameters current with 512Mb datasheet rev N |
|
// Timing parameters based on Speed Grade |
|
// SYMBOL UNITS DESCRIPTION |
//`define sg37E |
`define x16 |
|
`ifdef sg37E |
parameter TCK_MIN = 3750; // tCK ps Minimum Clock Cycle Time |
parameter TJIT_PER = 125; // tJIT(per) ps Period JItter |
parameter TJIT_DUTY = 125; // tJIT(duty) ps Half Period Jitter |
parameter TJIT_CC = 250; // tJIT(cc) ps Cycle to Cycle jitter |
parameter TERR_2PER = 175; // tERR(nper) ps Accumulated Error (2-cycle) |
parameter TERR_3PER = 225; // tERR(nper) ps Accumulated Error (3-cycle) |
parameter TERR_4PER = 250; // tERR(nper) ps Accumulated Error (4-cycle) |
parameter TERR_5PER = 250; // tERR(nper) ps Accumulated Error (5-cycle) |
parameter TERR_N1PER = 350; // tERR(nper) ps Accumulated Error (6-10-cycle) |
parameter TERR_N2PER = 450; // tERR(nper) ps Accumulated Error (11-50-cycle) |
parameter TQHS = 400; // tQHS ps Data hold skew factor |
parameter TAC = 500; // tAC ps DQ output access time from CK/CK# |
parameter TDS = 100; // tDS ps DQ and DM input setup time relative to DQS |
parameter TDH = 225; // tDH ps DQ and DM input hold time relative to DQS |
parameter TDQSCK = 450; // tDQSCK ps DQS output access time from CK/CK# |
parameter TDQSQ = 300; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access |
parameter TIS = 250; // tIS ps Input Setup Time |
parameter TIH = 375; // tIH ps Input Hold Time |
parameter TRC = 55000; // tRC ps Active to Active/Auto Refresh command time |
parameter TRCD = 15000; // tRCD ps Active to Read/Write command time |
parameter TWTR = 7500; // tWTR ps Write to Read command delay |
parameter TRP = 15000; // tRP ps Precharge command period |
parameter TRPA = 15000; // tRPA ps Precharge All period |
parameter TXARDS = 6; // tXARDS tCK Exit low power active power down to a read command |
parameter TXARD = 2; // tXARD tCK Exit active power down to a read command |
parameter TXP = 2; // tXP tCK Exit power down to a non-read command |
parameter TANPD = 3; // tANPD tCK ODT to power-down entry latency |
parameter TAXPD = 8; // tAXPD tCK ODT power-down exit latency |
parameter CL_TIME = 15000; // CL ps Minimum CAS Latency |
`else // ------ ----- ----------- |
`ifdef sg187E |
parameter TCK_MIN = 1875; // tCK ps Minimum Clock Cycle Time |
parameter TJIT_PER = 90; // tJIT(per) ps Period JItter |
parameter TJIT_DUTY = 75; // tJIT(duty) ps Half Period Jitter |
parameter TJIT_CC = 180; // tJIT(cc) ps Cycle to Cycle jitter |
parameter TERR_2PER = 132; // tERR(nper) ps Accumulated Error (2-cycle) |
parameter TERR_3PER = 157; // tERR(nper) ps Accumulated Error (3-cycle) |
parameter TERR_4PER = 175; // tERR(nper) ps Accumulated Error (4-cycle) |
parameter TERR_5PER = 188; // tERR(nper) ps Accumulated Error (5-cycle) |
parameter TERR_N1PER = 250; // tERR(nper) ps Accumulated Error (6-10-cycle) |
parameter TERR_N2PER = 425; // tERR(nper) ps Accumulated Error (11-50-cycle) |
parameter TQHS = 250; // tQHS ps Data hold skew factor |
parameter TAC = 350; // tAC ps DQ output access time from CK/CK# |
parameter TDS = 0; // tDS ps DQ and DM input setup time relative to DQS |
parameter TDH = 75; // tDH ps DQ and DM input hold time relative to DQS |
parameter TDQSCK = 300; // tDQSCK ps DQS output access time from CK/CK# |
parameter TDQSQ = 175; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access |
parameter TIS = 125; // tIS ps Input Setup Time |
parameter TIH = 200; // tIH ps Input Hold Time |
parameter TRC = 54000; // tRC ps Active to Active/Auto Refresh command time |
parameter TRCD = 13125; // tRCD ps Active to Read/Write command time |
parameter TWTR = 7500; // tWTR ps Write to Read command delay |
parameter TRP = 13125; // tRP ps Precharge command period |
parameter TRPA = 13125; // tRPA ps Precharge All period |
parameter TXARDS = 10; // tXARDS tCK Exit low power active power down to a read command |
parameter TXARD = 3; // tXARD tCK Exit active power down to a read command |
parameter TXP = 3; // tXP tCK Exit power down to a non-read command |
parameter TANPD = 4; // tANPD tCK ODT to power-down entry latency |
parameter TAXPD = 11; // tAXPD tCK ODT power-down exit latency |
parameter CL_TIME = 13125; // CL ps Minimum CAS Latency |
`else `ifdef sg25E |
parameter TCK_MIN = 2500; // tCK ps Minimum Clock Cycle Time |
parameter TJIT_PER = 100; // tJIT(per) ps Period JItter |
parameter TJIT_DUTY = 100; // tJIT(duty) ps Half Period Jitter |
parameter TJIT_CC = 200; // tJIT(cc) ps Cycle to Cycle jitter |
parameter TERR_2PER = 150; // tERR(nper) ps Accumulated Error (2-cycle) |
parameter TERR_3PER = 175; // tERR(nper) ps Accumulated Error (3-cycle) |
parameter TERR_4PER = 200; // tERR(nper) ps Accumulated Error (4-cycle) |
parameter TERR_5PER = 200; // tERR(nper) ps Accumulated Error (5-cycle) |
parameter TERR_N1PER = 300; // tERR(nper) ps Accumulated Error (6-10-cycle) |
parameter TERR_N2PER = 450; // tERR(nper) ps Accumulated Error (11-50-cycle) |
parameter TQHS = 300; // tQHS ps Data hold skew factor |
parameter TAC = 400; // tAC ps DQ output access time from CK/CK# |
parameter TDS = 50; // tDS ps DQ and DM input setup time relative to DQS |
parameter TDH = 125; // tDH ps DQ and DM input hold time relative to DQS |
parameter TDQSCK = 350; // tDQSCK ps DQS output access time from CK/CK# |
parameter TDQSQ = 200; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access |
parameter TIS = 175; // tIS ps Input Setup Time |
parameter TIH = 250; // tIH ps Input Hold Time |
parameter TRC = 55000; // tRC ps Active to Active/Auto Refresh command time |
parameter TRCD = 12500; // tRCD ps Active to Read/Write command time |
parameter TWTR = 7500; // tWTR ps Write to Read command delay |
parameter TRP = 12500; // tRP ps Precharge command period |
parameter TRPA = 12500; // tRPA ps Precharge All period |
parameter TXARDS = 8; // tXARDS tCK Exit low power active power down to a read command |
parameter TXARD = 2; // tXARD tCK Exit active power down to a read command |
parameter TXP = 2; // tXP tCK Exit power down to a non-read command |
parameter TANPD = 3; // tANPD tCK ODT to power-down entry latency |
parameter TAXPD = 10; // tAXPD tCK ODT power-down exit latency |
parameter CL_TIME = 12500; // CL ps Minimum CAS Latency |
`else `ifdef sg25 |
parameter TCK_MIN = 2500; // tCK ps Minimum Clock Cycle Time |
parameter TJIT_PER = 100; // tJIT(per) ps Period JItter |
parameter TJIT_DUTY = 100; // tJIT(duty) ps Half Period Jitter |
parameter TJIT_CC = 200; // tJIT(cc) ps Cycle to Cycle jitter |
parameter TERR_2PER = 150; // tERR(nper) ps Accumulated Error (2-cycle) |
parameter TERR_3PER = 175; // tERR(nper) ps Accumulated Error (3-cycle) |
parameter TERR_4PER = 200; // tERR(nper) ps Accumulated Error (4-cycle) |
parameter TERR_5PER = 200; // tERR(nper) ps Accumulated Error (5-cycle) |
parameter TERR_N1PER = 300; // tERR(nper) ps Accumulated Error (6-10-cycle) |
parameter TERR_N2PER = 450; // tERR(nper) ps Accumulated Error (11-50-cycle) |
parameter TQHS = 300; // tQHS ps Data hold skew factor |
parameter TAC = 400; // tAC ps DQ output access time from CK/CK# |
parameter TDS = 50; // tDS ps DQ and DM input setup time relative to DQS |
parameter TDH = 125; // tDH ps DQ and DM input hold time relative to DQS |
parameter TDQSCK = 350; // tDQSCK ps DQS output access time from CK/CK# |
parameter TDQSQ = 200; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access |
parameter TIS = 175; // tIS ps Input Setup Time |
parameter TIH = 250; // tIH ps Input Hold Time |
parameter TRC = 55000; // tRC ps Active to Active/Auto Refresh command time |
parameter TRCD = 15000; // tRCD ps Active to Read/Write command time |
parameter TWTR = 7500; // tWTR ps Write to Read command delay |
parameter TRP = 15000; // tRP ps Precharge command period |
parameter TRPA = 15000; // tRPA ps Precharge All period |
parameter TXARDS = 8; // tXARDS tCK Exit low power active power down to a read command |
parameter TXARD = 2; // tXARD tCK Exit active power down to a read command |
parameter TXP = 2; // tXP tCK Exit power down to a non-read command |
parameter TANPD = 3; // tANPD tCK ODT to power-down entry latency |
parameter TAXPD = 10; // tAXPD tCK ODT power-down exit latency |
parameter CL_TIME = 15000; // CL ps Minimum CAS Latency |
`else `ifdef sg3E |
parameter TCK_MIN = 3000; // tCK ps Minimum Clock Cycle Time |
parameter TJIT_PER = 125; // tJIT(per) ps Period JItter |
parameter TJIT_DUTY = 125; // tJIT(duty) ps Half Period Jitter |
parameter TJIT_CC = 250; // tJIT(cc) ps Cycle to Cycle jitter |
parameter TERR_2PER = 175; // tERR(nper) ps Accumulated Error (2-cycle) |
parameter TERR_3PER = 225; // tERR(nper) ps Accumulated Error (3-cycle) |
parameter TERR_4PER = 250; // tERR(nper) ps Accumulated Error (4-cycle) |
parameter TERR_5PER = 250; // tERR(nper) ps Accumulated Error (5-cycle) |
parameter TERR_N1PER = 350; // tERR(nper) ps Accumulated Error (6-10-cycle) |
parameter TERR_N2PER = 450; // tERR(nper) ps Accumulated Error (11-50-cycle) |
parameter TQHS = 340; // tQHS ps Data hold skew factor |
parameter TAC = 450; // tAC ps DQ output access time from CK/CK# |
parameter TDS = 100; // tDS ps DQ and DM input setup time relative to DQS |
parameter TDH = 175; // tDH ps DQ and DM input hold time relative to DQS |
parameter TDQSCK = 400; // tDQSCK ps DQS output access time from CK/CK# |
parameter TDQSQ = 240; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access |
parameter TIS = 200; // tIS ps Input Setup Time |
parameter TIH = 275; // tIH ps Input Hold Time |
parameter TRC = 54000; // tRC ps Active to Active/Auto Refresh command time |
parameter TRCD = 12000; // tRCD ps Active to Read/Write command time |
parameter TWTR = 7500; // tWTR ps Write to Read command delay |
parameter TRP = 12000; // tRP ps Precharge command period |
parameter TRPA = 12000; // tRPA ps Precharge All period |
parameter TXARDS = 7; // tXARDS tCK Exit low power active power down to a read command |
parameter TXARD = 2; // tXARD tCK Exit active power down to a read command |
parameter TXP = 2; // tXP tCK Exit power down to a non-read command |
parameter TANPD = 3; // tANPD tCK ODT to power-down entry latency |
parameter TAXPD = 8; // tAXPD tCK ODT power-down exit latency |
parameter CL_TIME = 12000; // CL ps Minimum CAS Latency |
`else `ifdef sg3 |
parameter TCK_MIN = 3000; // tCK ps Minimum Clock Cycle Time |
parameter TJIT_PER = 125; // tJIT(per) ps Period JItter |
parameter TJIT_DUTY = 125; // tJIT(duty) ps Half Period Jitter |
parameter TJIT_CC = 250; // tJIT(cc) ps Cycle to Cycle jitter |
parameter TERR_2PER = 175; // tERR(nper) ps Accumulated Error (2-cycle) |
parameter TERR_3PER = 225; // tERR(nper) ps Accumulated Error (3-cycle) |
parameter TERR_4PER = 250; // tERR(nper) ps Accumulated Error (4-cycle) |
parameter TERR_5PER = 250; // tERR(nper) ps Accumulated Error (5-cycle) |
parameter TERR_N1PER = 350; // tERR(nper) ps Accumulated Error (6-10-cycle) |
parameter TERR_N2PER = 450; // tERR(nper) ps Accumulated Error (11-50-cycle) |
parameter TQHS = 340; // tQHS ps Data hold skew factor |
parameter TAC = 450; // tAC ps DQ output access time from CK/CK# |
parameter TDS = 100; // tDS ps DQ and DM input setup time relative to DQS |
parameter TDH = 175; // tDH ps DQ and DM input hold time relative to DQS |
parameter TDQSCK = 400; // tDQSCK ps DQS output access time from CK/CK# |
parameter TDQSQ = 240; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access |
parameter TIS = 200; // tIS ps Input Setup Time |
parameter TIH = 275; // tIH ps Input Hold Time |
parameter TRC = 55000; // tRC ps Active to Active/Auto Refresh command time |
parameter TRCD = 15000; // tRCD ps Active to Read/Write command time |
parameter TWTR = 7500; // tWTR ps Write to Read command delay |
parameter TRP = 15000; // tRP ps Precharge command period |
parameter TRPA = 15000; // tRPA ps Precharge All period |
parameter TXARDS = 7; // tXARDS tCK Exit low power active power down to a read command |
parameter TXARD = 2; // tXARD tCK Exit active power down to a read command |
parameter TXP = 2; // tXP tCK Exit power down to a non-read command |
parameter TANPD = 3; // tANPD tCK ODT to power-down entry latency |
parameter TAXPD = 8; // tAXPD tCK ODT power-down exit latency |
parameter CL_TIME = 15000; // CL ps Minimum CAS Latency |
`else `define sg5E |
parameter TCK_MIN = 5000; // tCK ps Minimum Clock Cycle Time |
parameter TJIT_PER = 125; // tJIT(per) ps Period JItter |
parameter TJIT_DUTY = 150; // tJIT(duty) ps Half Period Jitter |
parameter TJIT_CC = 250; // tJIT(cc) ps Cycle to Cycle jitter |
parameter TERR_2PER = 175; // tERR(nper) ps Accumulated Error (2-cycle) |
parameter TERR_3PER = 225; // tERR(nper) ps Accumulated Error (3-cycle) |
parameter TERR_4PER = 250; // tERR(nper) ps Accumulated Error (4-cycle) |
parameter TERR_5PER = 250; // tERR(nper) ps Accumulated Error (5-cycle) |
parameter TERR_N1PER = 350; // tERR(nper) ps Accumulated Error (6-10-cycle) |
parameter TERR_N2PER = 450; // tERR(nper) ps Accumulated Error (11-50-cycle) |
parameter TQHS = 450; // tQHS ps Data hold skew factor |
parameter TAC = 600; // tAC ps DQ output access time from CK/CK# |
parameter TDS = 150; // tDS ps DQ and DM input setup time relative to DQS |
parameter TDH = 275; // tDH ps DQ and DM input hold time relative to DQS |
parameter TDQSCK = 500; // tDQSCK ps DQS output access time from CK/CK# |
parameter TDQSQ = 350; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access |
parameter TIS = 350; // tIS ps Input Setup Time |
parameter TIH = 475; // tIH ps Input Hold Time |
parameter TRC = 55000; // tRC ps Active to Active/Auto Refresh command time |
parameter TRCD = 15000; // tRCD ps Active to Read/Write command time |
parameter TWTR = 10000; // tWTR ps Write to Read command delay |
parameter TRP = 15000; // tRP ps Precharge command period |
parameter TRPA = 15000; // tRPA ps Precharge All period |
parameter TXARDS = 6; // tXARDS tCK Exit low power active power down to a read command |
parameter TXARD = 2; // tXARD tCK Exit active power down to a read command |
parameter TXP = 2; // tXP tCK Exit power down to a non-read command |
parameter TANPD = 3; // tANPD tCK ODT to power-down entry latency |
parameter TAXPD = 8; // tAXPD tCK ODT power-down exit latency |
parameter CL_TIME = 15000; // CL ps Minimum CAS Latency |
`endif `endif `endif `endif `endif `endif |
|
`ifdef x16 |
`ifdef sg187E |
parameter TFAW = 45000; // tFAW ps Four Bank Activate window |
`else `ifdef sg25E |
parameter TFAW = 45000; // tFAW ps Four Bank Activate window |
`else `ifdef sg25 |
parameter TFAW = 45000; // tFAW ps Four Bank Activate window |
`else // sg3E, sg3, sg37E, sg5E |
parameter TFAW = 50000; // tFAW ps Four Bank Activate window |
`endif `endif `endif |
`else // x4, x8 |
`ifdef sg187E |
parameter TFAW = 35000; // tFAW ps Four Bank Activate window |
`else `ifdef sg25E |
parameter TFAW = 35000; // tFAW ps Four Bank Activate window |
`else `ifdef sg25 |
parameter TFAW = 35000; // tFAW ps Four Bank Activate window |
`else // sg3E, sg3, sg37E, sg5E |
parameter TFAW = 37500; // tFAW ps Four Bank Activate window |
`endif `endif `endif |
`endif |
|
// Timing Parameters |
|
// Mode Register |
parameter AL_MIN = 0; // AL tCK Minimum Additive Latency |
parameter AL_MAX = 6; // AL tCK Maximum Additive Latency |
parameter CL_MIN = 3; // CL tCK Minimum CAS Latency |
parameter CL_MAX = 7; // CL tCK Maximum CAS Latency |
parameter WR_MIN = 2; // WR tCK Minimum Write Recovery |
parameter WR_MAX = 8; // WR tCK Maximum Write Recovery |
parameter BL_MIN = 4; // BL tCK Minimum Burst Length |
parameter BL_MAX = 8; // BL tCK Minimum Burst Length |
// Clock |
parameter TCK_MAX = 8000; // tCK ps Maximum Clock Cycle Time |
parameter TCH_MIN = 0.48; // tCH tCK Minimum Clock High-Level Pulse Width |
parameter TCH_MAX = 0.52; // tCH tCK Maximum Clock High-Level Pulse Width |
parameter TCL_MIN = 0.48; // tCL tCK Minimum Clock Low-Level Pulse Width |
parameter TCL_MAX = 0.52; // tCL tCK Maximum Clock Low-Level Pulse Width |
// Data |
parameter TLZ = TAC; // tLZ ps Data-out low-impedance window from CK/CK# |
parameter THZ = TAC; // tHZ ps Data-out high impedance window from CK/CK# |
parameter TDIPW = 0.35; // tDIPW tCK DQ and DM input Pulse Width |
// Data Strobe |
parameter TDQSH = 0.35; // tDQSH tCK DQS input High Pulse Width |
parameter TDQSL = 0.35; // tDQSL tCK DQS input Low Pulse Width |
parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time) |
parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time) |
parameter TWPRE = 0.35; // tWPRE tCK DQS Write Preamble |
parameter TWPST = 0.40; // tWPST tCK DQS Write Postamble |
parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition |
// Command and Address |
parameter TIPW = 0.6; // tIPW tCK Control and Address input Pulse Width |
parameter TCCD = 2; // tCCD tCK Cas to Cas command delay |
parameter TRAS_MIN = 40000; // tRAS ps Minimum Active to Precharge command time |
parameter TRAS_MAX =70000000; // tRAS ps Maximum Active to Precharge command time |
parameter TRTP = 7500; // tRTP ps Read to Precharge command delay |
parameter TWR = 15000; // tWR ps Write recovery time |
parameter TMRD = 2; // tMRD tCK Load Mode Register command cycle time |
parameter TDLLK = 200; // tDLLK tCK DLL locking time |
// Refresh |
parameter TRFC_MIN = 105000; // tRFC ps Refresh to Refresh Command interval minimum value |
parameter TRFC_MAX =70000000; // tRFC ps Refresh to Refresh Command Interval maximum value |
// Self Refresh |
parameter TXSNR = TRFC_MIN + 10000; // tXSNR ps Exit self refesh to a non-read command |
parameter TXSRD = 200; // tXSRD tCK Exit self refresh to a read command |
parameter TISXR = TIS; // tISXR ps CKE setup time during self refresh exit. |
// ODT |
parameter TAOND = 2; // tAOND tCK ODT turn-on delay |
parameter TAOFD = 2.5; // tAOFD tCK ODT turn-off delay |
parameter TAONPD = 2000; // tAONPD ps ODT turn-on (precharge power-down mode) |
parameter TAOFPD = 2000; // tAOFPD ps ODT turn-off (precharge power-down mode) |
parameter TMOD = 12000; // tMOD ps ODT enable in EMR to ODT pin transition |
// Power Down |
parameter TCKE = 3; // tCKE tCK CKE minimum high or low pulse width |
|
// Size Parameters based on Part Width |
|
`ifdef x4 |
parameter ADDR_BITS = 14; // Address Bits |
parameter ROW_BITS = 14; // Number of Address bits |
parameter COL_BITS = 11; // Number of Column bits |
parameter DM_BITS = 1; // Number of Data Mask bits |
parameter DQ_BITS = 4; // Number of Data bits |
parameter DQS_BITS = 1; // Number of Dqs bits |
parameter TRRD = 7500; // tRRD Active bank a to Active bank b command time |
`else `ifdef x8 |
parameter ADDR_BITS = 14; // Address Bits |
parameter ROW_BITS = 14; // Number of Address bits |
parameter COL_BITS = 10; // Number of Column bits |
parameter DM_BITS = 1; // Number of Data Mask bits |
parameter DQ_BITS = 8; // Number of Data bits |
parameter DQS_BITS = 1; // Number of Dqs bits |
parameter TRRD = 7500; // tRRD Active bank a to Active bank b command time |
`else `define x16 |
parameter ADDR_BITS = 13; // Address Bits |
parameter ROW_BITS = 13; // Number of Address bits |
parameter COL_BITS = 10; // Number of Column bits |
parameter DM_BITS = 2; // Number of Data Mask bits |
parameter DQ_BITS = 16; // Number of Data bits |
parameter DQS_BITS = 2; // Number of Dqs bits |
parameter TRRD = 10000; // tRRD Active bank a to Active bank b command time |
`endif `endif |
|
`ifdef QUAD_RANK |
`define DUAL_RANK // also define DUAL_RANK |
parameter CS_BITS = 4; // Number of Chip Select Bits |
parameter RANKS = 4; // Number of Chip Select Bits |
`else `ifdef DUAL_RANK |
parameter CS_BITS = 2; // Number of Chip Select Bits |
parameter RANKS = 2; // Number of Chip Select Bits |
`else |
parameter CS_BITS = 2; // Number of Chip Select Bits |
parameter RANKS = 1; // Number of Chip Select Bits |
`endif `endif |
|
// Size Parameters |
parameter BA_BITS = 2; // Set this parmaeter to control how many Bank Address bits |
// if MEM_BITS== 14, a DQ=16 each part, DQ=64 total (4 parts) => 1MB total (256KB each) |
// if MEM_BITS== 15, a DQ=16 each part, DQ=64 total (4 parts) => 2MB total (512KB each) |
// if MEM_BITS== 16, a DQ=16 each part, DQ=64 total (4 parts) => 4MB total (1MB each) |
// if MEM_BITS== 17, a DQ=16 each part, DQ=64 total (4 parts) => 8MB total (2MB each) |
//parameter MEM_BITS = 14; // Number of write data bursts can be stored in memory. The default is 2^10=1024. |
parameter MEM_BITS = 17; // Number of write data bursts can be stored in memory. |
parameter AP = 10; // the address bit that controls auto-precharge and precharge-all |
parameter BL_BITS = 3; // the number of bits required to count to MAX_BL |
parameter BO_BITS = 2; // the number of Burst Order Bits |
|
// Simulation parameters |
parameter STOP_ON_ERROR = 1; // If set to 1, the model will halt on command sequence/major errors |
parameter DEBUG = 0; // Turn on Debug messages |
parameter BUS_DELAY = 0; // delay in nanoseconds |
parameter RANDOM_OUT_DELAY = 0; // If set to 1, the model will put a random amount of delay on DQ/DQS during reads |
parameter RANDOM_SEED = 711689044; //seed value for random generator. |
|
parameter RDQSEN_PRE = 2; // DQS driving time prior to first read strobe |
parameter RDQSEN_PST = 1; // DQS driving time after last read strobe |
parameter RDQS_PRE = 2; // DQS low time prior to first read strobe |
parameter RDQS_PST = 1; // DQS low time after last valid read strobe |
parameter RDQEN_PRE = 0; // DQ/DM driving time prior to first read data |
parameter RDQEN_PST = 0; // DQ/DM driving time after last read data |
parameter WDQS_PRE = 1; // DQS half clock periods prior to first write strobe |
parameter WDQS_PST = 1; // DQS half clock periods after last valid write strobe |
/s3adsp1800/bench/verilog/include/ddr2_model_preload.v
0,0 → 1,50
// File intended to be included in the generate statement for each DDR2 part. |
// The following loads a vmem file, "sram.vmem" by default, into the SDRAM. |
|
// Wait until the DDR memory is initialised, and then magically |
// load it |
@(posedge dut.xilinx_s3adsp_ddr2.xilinx_s3adsp_ddr2_if.phy_init_done); |
//$display("%t: Loading DDR2",$time); |
|
$readmemh("sram.vmem", program_array); |
/* Now dish it out to the DDR2 model's memory */ |
for(ram_ptr = 0 ; ram_ptr < 4096 ; ram_ptr = ram_ptr + 1) |
begin |
|
// Construct the burst line, with every second word from where we |
// started, and picking the correct half of the word with i%2 |
program_word_ptr = ram_ptr *8; |
|
tmp_program_word = program_array[program_word_ptr+1]; |
ddr2_ram_mem_line[15:0] = tmp_program_word[15 + (i*16):(i*16)]; |
|
tmp_program_word = program_array[program_word_ptr]; |
ddr2_ram_mem_line[31:16] = tmp_program_word[15 + (i*16):(i*16)]; |
|
tmp_program_word = program_array[program_word_ptr+3]; |
ddr2_ram_mem_line[47:32] = tmp_program_word[15 + (i*16):(i*16)]; |
|
tmp_program_word = program_array[program_word_ptr+2]; |
ddr2_ram_mem_line[63:48] = tmp_program_word[15 + (i*16):(i*16)]; |
|
tmp_program_word = program_array[program_word_ptr+5]; |
ddr2_ram_mem_line[79:64] = tmp_program_word[15 + (i*16):(i*16)]; |
|
tmp_program_word = program_array[program_word_ptr+4]; |
ddr2_ram_mem_line[95:80] = tmp_program_word[15 + (i*16):(i*16)]; |
|
tmp_program_word = program_array[program_word_ptr+7]; |
ddr2_ram_mem_line[111:96] = tmp_program_word[15 + (i*16):(i*16)]; |
|
tmp_program_word = program_array[program_word_ptr+6]; |
ddr2_ram_mem_line[127:112] = tmp_program_word[15 + (i*16):(i*16)]; |
|
// Put this assembled line into the RAM using its memory writing TASK |
u_mem0.memory_write(2'b00,ram_ptr[19:7], |
{ram_ptr[6:0],3'b000},ddr2_ram_mem_line); |
|
//$display("Writing 0x%h, ramline=%d",ddr2_ram_mem_line, ram_ptr); |
|
end // for (ram_ptr = 0 ; ram_ptr < ... |
$display("(%t) * DDR2 RAM %1d preloaded",$time, i); |
|
/s3adsp1800/bench/verilog/include/synthesis-defines.v
0,0 → 1,2
// Nothing in here, just providing synthesis-defines.v for files that include |
// it (clkgen, for one.) |
/s3adsp1800/bench/verilog/include/timescale.v
0,0 → 1,2
`timescale 1ns/1ps |
/s3adsp1800/bench/verilog/orpsoc_testbench.v
0,0 → 1,531
////////////////////////////////////////////////////////////////////// |
/// //// |
/// ORPSoC Spartan 3A DSP 1800 board testbench //// |
/// //// |
/// Instantiate ORPSoC, monitors, provide stimulus //// |
/// //// |
/// Julius Baxter, julius@opencores.org //// |
/// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009,2010,2011 Authors and 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
`include "orpsoc-defines.v" |
`include "orpsoc-testbench-defines.v" |
`include "test-defines.v" |
`include "timescale.v" |
// Xilinx simulation: |
`include "glbl.v" |
|
module orpsoc_testbench; |
|
// Clock and reset signal registers |
reg clk = 0; |
reg rst_n = 1; // Active LOW |
|
always |
#((`BOARD_CLOCK_PERIOD)/2) clk <= ~clk; |
|
// Reset, ACTIVE LOW |
initial |
begin |
#1; |
repeat (32) @(negedge clk) |
rst_n <= 1; |
repeat (32) @(negedge clk) |
rst_n <= 0; |
repeat (32) @(negedge clk) |
rst_n <= 1; |
end |
|
// Include design parameters file |
`include "orpsoc-params.v" |
|
// Pullup bus for I2C |
tri1 i2c_scl, i2c_sda; |
|
`ifdef JTAG_DEBUG |
wire tdo_pad_o; |
wire tck_pad_i; |
wire tms_pad_i; |
wire tdi_pad_i; |
`endif |
`ifdef UART0 |
wire uart0_stx_pad_o; |
wire uart0_srx_pad_i; |
`endif |
`ifdef GPIO0 |
wire [gpio0_io_width-1:0] gpio0_io; |
`endif |
`ifdef SPI0 |
wire spi0_mosi_o; |
wire spi0_miso_i; |
wire spi0_sck_o; |
wire spi0_hold_n_o; |
wire spi0_w_n_o; |
wire [spi0_ss_width-1:0] spi0_ss_o; |
`endif |
`ifdef ETH0 |
wire mtx_clk_o; |
wire [3:0] ethphy_mii_tx_d; |
wire ethphy_mii_tx_en; |
wire ethphy_mii_tx_err; |
wire mrx_clk_o; |
wire [3:0] mrxd_o; |
wire mrxdv_o; |
wire mrxerr_o; |
wire mcoll_o; |
wire mcrs_o; |
wire ethphy_rst_n; |
wire eth0_mdc_pad_o; |
wire eth0_md_pad_io; |
`endif |
`ifdef XILINX_DDR2 |
`include "s3adsp_ddr2_parameters_0.v" |
localparam DEVICE_WIDTH = 16; // Memory device data width |
localparam REG_ENABLE = `REGISTERED; // registered addr/ctrl |
|
localparam real CLK_PERIOD_NS = 7519.0 / 1000.0; |
// Delay for DQS signal during operation |
localparam real TPROP_DQS = 0.00; |
localparam real TPROP_DQS_RD = 0.05; |
localparam real TPROP_PCB_CTRL = 0.00; |
localparam real TPROP_PCB_DATA = 0.00; |
localparam real TPROP_PCB_DATA_RD = 0.00; |
|
wire [`DATA_WIDTH-1:0] ddr2_dq_sdram; |
wire [`DATA_STROBE_WIDTH-1:0] ddr2_dqs_sdram; |
|
// ddr2_dqs_n signal will be driven only in case of differential dqs is enabled. |
wire [`DATA_STROBE_WIDTH-1:0] ddr2_dqs_n_sdram; |
wire [`DATA_MASK_WIDTH-1:0] ddr2_dm_sdram; |
reg [`DATA_MASK_WIDTH-1:0] ddr2_dm_sdram_tmp; |
reg [`CLK_WIDTH-1:0] ddr2_clk_sdram; |
reg [`CLK_WIDTH-1:0] ddr2_clk_n_sdram; |
reg [`ROW_ADDRESS-1:0] ddr2_address_sdram; |
reg [`BANK_ADDRESS-1:0] ddr2_ba_sdram; |
reg ddr2_ras_n_sdram; |
reg ddr2_cas_n_sdram; |
reg ddr2_we_n_sdram; |
reg ddr2_cs_n_sdram; |
reg ddr2_cke_sdram; |
reg ddr2_odt_sdram; |
|
|
wire [`DATA_WIDTH-1:0] ddr2_dq_fpga; |
wire [`DATA_STROBE_WIDTH-1:0] ddr2_dqs_fpga; |
|
// ddr2_dqs_n signal will be driven only in case of differential dqs is enabled. |
wire [`DATA_STROBE_WIDTH-1:0] ddr2_dqs_n_fpga; |
wire [`DATA_MASK_WIDTH-1:0] ddr2_dm_fpga; |
wire [`CLK_WIDTH-1:0] ddr2_clk_fpga; |
wire [`CLK_WIDTH-1:0] ddr2_clk_n_fpga; |
wire [`ROW_ADDRESS-1:0] ddr2_address_fpga; |
wire [`BANK_ADDRESS-1:0] ddr2_ba_fpga; |
wire ddr2_ras_n_fpga; |
wire ddr2_cas_n_fpga; |
wire ddr2_we_n_fpga; |
wire ddr2_cs_n_fpga; |
wire ddr2_cke_fpga; |
wire ddr2_odt_fpga; |
|
wire ddr2_rst_dqs_div_loop; |
|
`endif |
|
orpsoc_top dut |
( |
`ifdef JTAG_DEBUG |
.tms_pad_i (tms_pad_i), |
.tck_pad_i (tck_pad_i), |
.tdi_pad_i (tdi_pad_i), |
.tdo_pad_o (tdo_pad_o), |
`endif |
`ifdef XILINX_DDR2 |
.ddr2_ras_n (ddr2_ras_n_fpga), |
.ddr2_cas_n (ddr2_cas_n_fpga), |
.ddr2_we_n (ddr2_we_n_fpga), |
.ddr2_cs_n (ddr2_cs_n_fpga), |
.ddr2_cke (ddr2_cke_fpga), |
.ddr2_odt (ddr2_odt_fpga), |
.ddr2_dm (ddr2_dm_fpga), |
.ddr2_dq (ddr2_dq_fpga), |
.ddr2_dqs (ddr2_dqs_fpga), |
.ddr2_dqs_n (ddr2_dqs_n_fpga), |
.ddr2_ck (ddr2_clk_fpga), |
.ddr2_ck_n (ddr2_clk_n_fpga), |
.ddr2_ba (ddr2_ba_fpga), |
.ddr2_a (ddr2_address_fpga), |
.ddr2_rst_dqs_div_in (ddr2_rst_dqs_div_loop), |
.ddr2_rst_dqs_div_out (ddr2_rst_dqs_div_loop), |
`endif |
|
`ifdef UART0 |
.uart0_stx_pad_o (uart0_stx_pad_o), |
.uart0_srx_pad_i (uart0_srx_pad_i), |
.uart0_stx_expheader_pad_o (uart0_stx_pad_o), |
.uart0_srx_expheader_pad_i (uart0_srx_pad_i), |
`endif |
`ifdef SPI0 |
.spi0_sck_o (spi0_sck_o), |
.spi0_miso_i (spi0_miso_i), |
.spi0_mosi_o (spi0_mosi_o), |
.spi0_ss_o (spi0_ss_o), |
`endif |
`ifdef I2C0 |
.i2c0_sda_io (i2c_sda), |
.i2c0_scl_io (i2c_scl), |
`endif |
`ifdef GPIO0 |
.gpio0_io (gpio0_io), |
`endif |
`ifdef ETH0 |
.eth0_tx_clk (mtx_clk_o), |
.eth0_tx_data (ethphy_mii_tx_d), |
.eth0_tx_en (ethphy_mii_tx_en), |
.eth0_tx_er (ethphy_mii_tx_err), |
.eth0_rx_clk (mrx_clk_o), |
.eth0_rx_data (mrxd_o), |
.eth0_dv (mrxdv_o), |
.eth0_rx_er (mrxerr_o), |
.eth0_col (mcoll_o), |
.eth0_crs (mcrs_o), |
.eth0_rst_n_o (ethphy_rst_n), |
.eth0_mdc_pad_o (eth0_mdc_pad_o), |
.eth0_md_pad_io (eth0_md_pad_io), |
`endif // `ifdef ETH0 |
|
.sys_clk_i (clk), |
|
.rst_n_pad_i (rst_n) |
); |
|
// |
// Instantiate OR1200 monitor |
// |
or1200_monitor monitor(); |
|
`ifndef SIM_QUIET |
`define CPU_ic_top or1200_ic_top |
`define CPU_dc_top or1200_dc_top |
wire ic_en = orpsoc_testbench.dut.or1200_top0.or1200_ic_top.ic_en; |
always @(posedge ic_en) |
$display("Or1200 IC enabled at %t", $time); |
|
wire dc_en = orpsoc_testbench.dut.or1200_top0.or1200_dc_top.dc_en; |
always @(posedge dc_en) |
$display("Or1200 DC enabled at %t", $time); |
`endif |
|
|
`ifdef JTAG_DEBUG |
`ifdef VPI_DEBUG |
// Debugging interface |
vpi_debug_module vpi_dbg |
( |
.tms(tms_pad_i), |
.tck(tck_pad_i), |
.tdi(tdi_pad_i), |
.tdo(tdo_pad_o) |
); |
`else |
// If no VPI debugging, tie off JTAG inputs |
assign tdi_pad_i = 1; |
assign tck_pad_i = 0; |
assign tms_pad_i = 1; |
`endif // !`ifdef VPI_DEBUG_ENABLE |
`endif // `ifdef JTAG_DEBUG |
|
`ifdef SPI0 |
// SPI flash memory - M25P16 compatible SPI protocol |
AT26DFxxx |
#(.MEMSIZE(2048*1024)) // 2MB flash on ML501 |
spi0_flash |
(// Outputs |
.SO (spi0_miso_i), |
// Inputs |
.CSB (spi0_ss_o), |
.SCK (spi0_sck_o), |
.SI (spi0_mosi_o), |
.WPB (1'b1) |
); |
|
|
`endif // `ifdef SPI0 |
|
`ifdef ETH0 |
|
/* TX/RXes packets and checks them, enabled when ethernet MAC is */ |
// Disabled for now - Julius `include "eth_stim.v" |
|
eth_phy eth_phy0 |
( |
// Outputs |
.mtx_clk_o (mtx_clk_o), |
.mrx_clk_o (mrx_clk_o), |
.mrxd_o (mrxd_o[3:0]), |
.mrxdv_o (mrxdv_o), |
.mrxerr_o (mrxerr_o), |
.mcoll_o (mcoll_o), |
.mcrs_o (mcrs_o), |
.link_o (), |
.speed_o (), |
.duplex_o (), |
.smii_clk_i (1'b0), |
.smii_sync_i (1'b0), |
.smii_rx_o (), |
// Inouts |
.md_io (eth0_md_pad_io), |
// Inputs |
`ifndef ETH0_PHY_RST |
// If no reset out from the design, hook up to the board's active low rst |
.m_rst_n_i (rst_n), |
`else |
.m_rst_n_i (ethphy_rst_n), |
`endif |
.mtxd_i (ethphy_mii_tx_d[3:0]), |
.mtxen_i (ethphy_mii_tx_en), |
.mtxerr_i (ethphy_mii_tx_err), |
.mdc_i (eth0_mdc_pad_o)); |
|
`endif // `ifdef ETH0 |
|
`ifdef XILINX_DDR2 |
|
always @( * ) begin |
ddr2_clk_sdram <= #(TPROP_PCB_CTRL) ddr2_clk_fpga; |
ddr2_clk_n_sdram <= #(TPROP_PCB_CTRL) ddr2_clk_n_fpga; |
ddr2_address_sdram <= #(TPROP_PCB_CTRL) ddr2_address_fpga; |
ddr2_ba_sdram <= #(TPROP_PCB_CTRL) ddr2_ba_fpga; |
ddr2_ras_n_sdram <= #(TPROP_PCB_CTRL) ddr2_ras_n_fpga; |
ddr2_cas_n_sdram <= #(TPROP_PCB_CTRL) ddr2_cas_n_fpga; |
ddr2_we_n_sdram <= #(TPROP_PCB_CTRL) ddr2_we_n_fpga; |
ddr2_cs_n_sdram <= #(TPROP_PCB_CTRL) ddr2_cs_n_fpga; |
ddr2_cke_sdram <= #(TPROP_PCB_CTRL) ddr2_cke_fpga; |
ddr2_odt_sdram <= #(TPROP_PCB_CTRL) ddr2_odt_fpga; |
ddr2_dm_sdram_tmp <= #(TPROP_PCB_DATA) ddr2_dm_fpga;//DM signal generation |
end // always @ ( * ) |
|
assign ddr2_dm_sdram = ddr2_dm_sdram_tmp; |
|
|
// Model delays on bi-directional BUS |
genvar dqwd; |
generate |
for (dqwd = 0;dqwd < `DATA_WIDTH;dqwd = dqwd+1) begin : dq_delay |
wiredelay # |
( |
.Delay_g (TPROP_PCB_DATA), |
.Delay_rd (TPROP_PCB_DATA_RD) |
) |
u_delay_dq |
( |
.A (ddr2_dq_fpga[dqwd]), |
.B (ddr2_dq_sdram[dqwd]), |
.reset (rst_n) |
); |
end |
endgenerate |
genvar dqswd; |
generate |
for (dqswd = 0;dqswd < `DATA_STROBE_WIDTH;dqswd = dqswd+1) |
begin : dqs_delay |
wiredelay # |
( |
.Delay_g (TPROP_DQS), |
.Delay_rd (TPROP_DQS_RD) |
) |
u_delay_dqs |
( |
.A (ddr2_dqs_fpga[dqswd]), |
.B (ddr2_dqs_sdram[dqswd]), |
.reset (rst_n) |
); |
|
wiredelay # |
( |
.Delay_g (TPROP_DQS), |
.Delay_rd (TPROP_DQS_RD) |
) |
u_delay_dqs_n |
( |
.A (ddr2_dqs_n_fpga[dqswd]), |
.B (ddr2_dqs_n_sdram[dqswd]), |
.reset (rst_n) |
); |
end |
endgenerate |
|
|
assign ddr2_dm_sdram = ddr2_dm_sdram_tmp; |
//parameter NUM_PROGRAM_WORDS=1048576; |
parameter NUM_PROGRAM_WORDS=262144; |
integer ram_ptr, program_word_ptr, k; |
reg [31:0] tmp_program_word; |
reg [31:0] program_array [0:NUM_PROGRAM_WORDS-1]; // 256k words = 1MB |
reg [8*16-1:0] ddr2_ram_mem_line; //8*16-bits= 8 shorts (half-words) |
genvar i,j; |
|
generate |
for(i = 0; i < `DATA_STROBE_WIDTH/2; i = i+1) begin : gen_bytes |
|
initial |
begin |
`ifdef PRELOAD_RAM |
`include "ddr2_model_preload.v" |
`endif |
end |
|
ddr2_model u_mem0 |
( |
.ck (ddr2_clk_sdram[i]), |
.ck_n (ddr2_clk_n_sdram[i]), |
.cke (ddr2_cke_sdram), |
.cs_n (ddr2_cs_n_sdram), |
.ras_n (ddr2_ras_n_sdram), |
.cas_n (ddr2_cas_n_sdram), |
.we_n (ddr2_we_n_sdram), |
.dm_rdqs (ddr2_dm_sdram[(2*(i+1))-1 : i*2]), |
.ba (ddr2_ba_sdram), |
.addr (ddr2_address_sdram), |
.dq (ddr2_dq_sdram[(16*(i+1))-1 : i*16]), |
.dqs (ddr2_dqs_sdram[(2*(i+1))-1 : i*2]), |
.dqs_n (ddr2_dqs_n_sdram[(2*(i+1))-1 : i*2]), |
.rdqs_n (), |
.odt (ddr2_odt_sdram) |
); |
end // block: gen_bytes |
endgenerate |
|
task ddr2_read32; |
input [31:0] addr; |
output [31:0] word; |
begin |
// TODO fill this in |
word = 0; |
end |
endtask // ddr2_read32 |
|
`endif // `ifdef XILINX_DDR2 |
|
`ifdef VCD |
reg vcd_go = 0; |
always @(vcd_go) |
begin |
|
`ifdef VCD_DELAY |
#(`VCD_DELAY); |
`endif |
|
// Delay by x insns |
`ifdef VCD_DELAY_INSNS |
#10; // Delay until after the value becomes valid |
while (monitor.insns < `VCD_DELAY_INSNS) |
@(posedge clk); |
`endif |
|
`ifdef SIMULATOR_MODELSIM |
// Modelsim can GZip VCDs on the fly if given in the suffix |
`define VCD_SUFFIX ".vcd.gz" |
`else |
`define VCD_SUFFIX ".vcd" |
`endif |
|
`ifndef SIM_QUIET |
$display("* VCD in %s\n", {"../out/",`TEST_NAME_STRING,`VCD_SUFFIX}); |
`endif |
$dumpfile({"../out/",`TEST_NAME_STRING,`VCD_SUFFIX}); |
`ifndef VCD_DEPTH |
`define VCD_DEPTH 0 |
`endif |
$dumpvars(`VCD_DEPTH); |
|
end |
`endif // `ifdef VCD |
|
initial |
begin |
`ifndef SIM_QUIET |
$display("\n* Starting simulation of design RTL.\n* Test: %s\n", |
`TEST_NAME_STRING ); |
`endif |
|
`ifdef VCD |
vcd_go = 1; |
`endif |
|
end // initial begin |
|
`ifdef END_TIME |
initial begin |
#(`END_TIME); |
`ifndef SIM_QUIET |
$display("* Finish simulation due to END_TIME being set at %t", $time); |
`endif |
$finish; |
end |
`endif |
|
`ifdef END_INSNS |
initial begin |
#10 |
while (monitor.insns < `END_INSNS) |
@(posedge clk); |
`ifndef SIM_QUIET |
$display("* Finish simulation due to END_INSNS count (%d) reached at %t", |
`END_INSNS, $time); |
`endif |
$finish; |
end |
`endif |
|
`ifdef UART0 |
// |
// UART0 decoder |
// |
uart_decoder |
#( |
.uart_baudrate_period_ns(8680) // 115200 baud = period 8.68uS |
) |
uart0_decoder |
( |
.clk(clk), |
.uart_tx(uart0_stx_pad_o) |
); |
|
// Loopback UART lines |
assign uart0_srx_pad_i = uart0_stx_pad_o; |
|
`endif // `ifdef UART0 |
|
endmodule // orpsoc_testbench |
|
// Local Variables: |
// verilog-library-directories:("." "../../rtl/verilog/orpsoc_top") |
// verilog-library-files:() |
// verilog-library-extensions:(".v" ".h") |
// End: |
|
/s3adsp1800/rtl/verilog/clkgen/clkgen.v
0,0 → 1,210
/* |
* |
* Clock, reset generation unit for s3adsp1800 board |
* |
* Implements clock generation according to design defines |
* |
*/ |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009, 2010 Authors and 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
`include "orpsoc-defines.v" |
`include "synthesis-defines.v" |
|
module clkgen |
( |
// Main clocks in, depending on board |
sys_clk_i, |
|
// Wishbone clock and reset out |
wb_clk_o, |
wb_rst_o, |
|
// JTAG clock |
`ifdef JTAG_DEBUG |
tck_pad_i, |
dbg_tck_o, |
`endif |
// Main memory clocks |
`ifdef XILINX_DDR2 |
clk133_o, |
`endif |
|
// Asynchronous, active low reset in |
rst_n_pad_i |
|
); |
|
input sys_clk_i; |
|
output wb_rst_o; |
output wb_clk_o; |
|
`ifdef JTAG_DEBUG |
input tck_pad_i; |
output dbg_tck_o; |
`endif |
|
`ifdef XILINX_DDR2 |
output clk133_o; |
`endif |
|
// Asynchronous, active low reset (pushbutton, typically) |
input rst_n_pad_i; |
|
// First, deal with the asychronous reset |
wire async_rst; |
wire async_rst_n; |
|
// Xilinx synthesis tools appear cluey enough to instantiate buffers when and |
// where they're needed, so we do simple assigns for this tech. |
assign async_rst_n = rst_n_pad_i; |
|
// Everyone likes active-high reset signals... |
assign async_rst = ~async_rst_n; |
|
|
`ifdef JTAG_DEBUG |
assign dbg_tck_o = tck_pad_i; |
`endif |
|
// |
// Declare synchronous reset wires here |
// |
|
// An active-low synchronous reset signal (usually a PLL lock signal) |
wire sync_rst_n; |
|
// An active-low synchronous reset from ethernet PLL |
wire sync_eth_rst_n; |
|
// IBUF for sys_clk_i |
wire sys_clk; |
IBUFG ibufg0 |
(.I(sys_clk_i), .O(sys_clk)); |
|
|
/* DCM0 wires */ |
wire dcm0_clk0_prebufg, dcm0_clk0; |
wire dcm0_clkfx_prebufg, dcm0_clkfx; |
wire dcm0_clkdv_prebufg, dcm0_clkdv; |
wire dcm0_locked; |
|
|
/* DCM providing main system/Wishbone clock */ |
DCM_SP #( .CLK_FEEDBACK("1X"), |
// 125 / 5 = 25 MHz |
.CLKDV_DIVIDE(5), |
// 125 * 2/8 = 31.25Mhz |
.CLKFX_DIVIDE(8), |
.CLKFX_MULTIPLY(2), |
// Clkin = 125 Mhz |
.CLKIN_PERIOD(8.000), |
.CLKIN_DIVIDE_BY_2("FALSE"), |
.CLKOUT_PHASE_SHIFT("NONE"), .DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), |
.DFS_FREQUENCY_MODE("LOW"), .DLL_FREQUENCY_MODE("LOW"), |
.DUTY_CYCLE_CORRECTION("TRUE"), .FACTORY_JF(16'hC080), |
.PHASE_SHIFT(0), .STARTUP_WAIT("FALSE") ) |
DCM_SP_INST |
( |
.CLKFB(dcm0_clk0), |
.CLKIN(sys_clk), |
.DSSEN(1'b0), |
.PSCLK(1'b0), |
.PSEN(1'b0), |
.PSINCDEC(1'b0), |
.RST(1'b0), |
.CLKDV(dcm0_clkdv_prebufg), |
.CLKFX(dcm0_clkfx_prebufg), |
.CLKFX180(), |
.CLK0(dcm0_clk0_prebufg), |
.CLK2X(), |
.CLK2X180(), |
.CLK90(), |
.CLK180(), |
.CLK270(), |
.LOCKED(dcm0_locked), |
.PSDONE(), |
.STATUS()); |
|
BUFG dcm0_clk0_bufg |
(// Outputs |
.O (dcm0_clk0), |
// Inputs |
.I (dcm0_clk0_prebufg)); |
|
BUFG dcm0_clkfx_bufg |
(// Outputs |
.O (dcm0_clkfx), |
// Inputs |
.I (dcm0_clkfx_prebufg)); |
|
BUFG dcm0_clkdv_bufg |
(// Outputs |
.O (dcm0_clkdv), |
// Inputs |
.I (dcm0_clkdv_prebufg)); |
|
assign wb_clk_o = dcm0_clkdv; |
assign sync_rst_n = dcm0_locked; |
|
`ifdef XILINX_DDR2 |
assign clk133_o = dcm0_clk0; // 125 MHz for now |
`endif |
|
// |
// Reset generation |
// |
// |
|
// Reset generation for wishbone |
reg [15:0] wb_rst_shr; |
always @(posedge wb_clk_o or posedge async_rst) |
if (async_rst) |
wb_rst_shr <= 16'hffff; |
else |
wb_rst_shr <= {wb_rst_shr[14:0], ~(sync_rst_n)}; |
|
assign wb_rst_o = wb_rst_shr[15]; |
|
|
`ifdef XILINX_DDR2 |
/* |
// Reset generation for DDR2 controller |
reg [15:0] ddr2_if_rst_shr; |
always @(posedge ddr2_if_clk_o or posedge async_rst) |
if (async_rst) |
ddr2_if_rst_shr <= 16'hffff; |
else |
ddr2_if_rst_shr <= {ddr2_if_rst_shr[14:0], ~(sync_rst_n)}; |
|
assign ddr2_if_rst_o = ddr2_if_rst_shr[15]; |
*/ |
`endif |
|
|
endmodule // clkgen |
/s3adsp1800/rtl/verilog/include/ethmac_defines.v
0,0 → 1,246
////////////////////////////////////////////////////////////////////// |
//// //// |
//// eth_defines.v //// |
//// //// |
//// This file is part of the Ethernet IP core project //// |
//// http://opencores.org/project,ethmac //// |
//// //// |
//// Author(s): //// |
//// - Igor Mohor (igorM@opencores.org) //// |
//// //// |
//// Modified by: //// |
//// - Julius Baxter (julius@opencores.org) //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001, 2002 Authors //// |
//// //// |
//// 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
|
|
//`define ETH_BIST // Bist for usage with Virtual Silicon RAMS |
|
`define ETH_MBIST_CTRL_WIDTH 3 // width of MBIST control bus |
|
// Generic FIFO implementation - hopefully synthesizable with Synplify |
//`define ETH_FIFO_GENERIC |
// specific elements. |
`define ETH_FIFO_XILINX |
//`define ETH_FIFO_RAMB18 |
|
|
`define ETH_MODER_ADR 8'h0 // 0x0 |
`define ETH_INT_SOURCE_ADR 8'h1 // 0x4 |
`define ETH_INT_MASK_ADR 8'h2 // 0x8 |
`define ETH_IPGT_ADR 8'h3 // 0xC |
`define ETH_IPGR1_ADR 8'h4 // 0x10 |
`define ETH_IPGR2_ADR 8'h5 // 0x14 |
`define ETH_PACKETLEN_ADR 8'h6 // 0x18 |
`define ETH_COLLCONF_ADR 8'h7 // 0x1C |
`define ETH_TX_BD_NUM_ADR 8'h8 // 0x20 |
`define ETH_CTRLMODER_ADR 8'h9 // 0x24 |
`define ETH_MIIMODER_ADR 8'hA // 0x28 |
`define ETH_MIICOMMAND_ADR 8'hB // 0x2C |
`define ETH_MIIADDRESS_ADR 8'hC // 0x30 |
`define ETH_MIITX_DATA_ADR 8'hD // 0x34 |
`define ETH_MIIRX_DATA_ADR 8'hE // 0x38 |
`define ETH_MIISTATUS_ADR 8'hF // 0x3C |
`define ETH_MAC_ADDR0_ADR 8'h10 // 0x40 |
`define ETH_MAC_ADDR1_ADR 8'h11 // 0x44 |
`define ETH_HASH0_ADR 8'h12 // 0x48 |
`define ETH_HASH1_ADR 8'h13 // 0x4C |
`define ETH_TX_CTRL_ADR 8'h14 // 0x50 |
`define ETH_RX_CTRL_ADR 8'h15 // 0x54 |
`define ETH_DBG_ADR 8'h16 // 0x58 |
|
|
`define ETH_MODER_DEF_0 8'h00 |
`define ETH_MODER_DEF_1 8'hA0 |
`define ETH_MODER_DEF_2 1'h0 |
`define ETH_INT_MASK_DEF_0 7'h0 |
`define ETH_IPGT_DEF_0 7'h12 |
`define ETH_IPGR1_DEF_0 7'h0C |
`define ETH_IPGR2_DEF_0 7'h12 |
`define ETH_PACKETLEN_DEF_0 8'h00 |
`define ETH_PACKETLEN_DEF_1 8'h06 |
`define ETH_PACKETLEN_DEF_2 8'h40 |
`define ETH_PACKETLEN_DEF_3 8'h00 |
`define ETH_COLLCONF_DEF_0 6'h3f |
`define ETH_COLLCONF_DEF_2 4'hF |
`define ETH_TX_BD_NUM_DEF_0 8'h40 |
`define ETH_CTRLMODER_DEF_0 3'h0 |
`define ETH_MIIMODER_DEF_0 8'h64 |
`define ETH_MIIMODER_DEF_1 1'h0 |
`define ETH_MIIADDRESS_DEF_0 5'h00 |
`define ETH_MIIADDRESS_DEF_1 5'h00 |
`define ETH_MIITX_DATA_DEF_0 8'h00 |
`define ETH_MIITX_DATA_DEF_1 8'h00 |
`define ETH_MIIRX_DATA_DEF 16'h0000 // not written from WB |
`define ETH_MAC_ADDR0_DEF_0 8'h00 |
`define ETH_MAC_ADDR0_DEF_1 8'h00 |
`define ETH_MAC_ADDR0_DEF_2 8'h00 |
`define ETH_MAC_ADDR0_DEF_3 8'h00 |
`define ETH_MAC_ADDR1_DEF_0 8'h00 |
`define ETH_MAC_ADDR1_DEF_1 8'h00 |
`define ETH_HASH0_DEF_0 8'h00 |
`define ETH_HASH0_DEF_1 8'h00 |
`define ETH_HASH0_DEF_2 8'h00 |
`define ETH_HASH0_DEF_3 8'h00 |
`define ETH_HASH1_DEF_0 8'h00 |
`define ETH_HASH1_DEF_1 8'h00 |
`define ETH_HASH1_DEF_2 8'h00 |
`define ETH_HASH1_DEF_3 8'h00 |
`define ETH_TX_CTRL_DEF_0 8'h00 // |
`define ETH_TX_CTRL_DEF_1 8'h00 // |
`define ETH_TX_CTRL_DEF_2 1'h0 // |
`define ETH_RX_CTRL_DEF_0 8'h00 |
`define ETH_RX_CTRL_DEF_1 8'h00 |
|
|
`define ETH_MODER_WIDTH_0 8 |
`define ETH_MODER_WIDTH_1 8 |
`define ETH_MODER_WIDTH_2 1 |
`define ETH_INT_SOURCE_WIDTH_0 7 |
`define ETH_INT_MASK_WIDTH_0 7 |
`define ETH_IPGT_WIDTH_0 7 |
`define ETH_IPGR1_WIDTH_0 7 |
`define ETH_IPGR2_WIDTH_0 7 |
`define ETH_PACKETLEN_WIDTH_0 8 |
`define ETH_PACKETLEN_WIDTH_1 8 |
`define ETH_PACKETLEN_WIDTH_2 8 |
`define ETH_PACKETLEN_WIDTH_3 8 |
`define ETH_COLLCONF_WIDTH_0 6 |
`define ETH_COLLCONF_WIDTH_2 4 |
`define ETH_TX_BD_NUM_WIDTH_0 8 |
`define ETH_CTRLMODER_WIDTH_0 3 |
`define ETH_MIIMODER_WIDTH_0 8 |
`define ETH_MIIMODER_WIDTH_1 1 |
`define ETH_MIICOMMAND_WIDTH_0 3 |
`define ETH_MIIADDRESS_WIDTH_0 5 |
`define ETH_MIIADDRESS_WIDTH_1 5 |
`define ETH_MIITX_DATA_WIDTH_0 8 |
`define ETH_MIITX_DATA_WIDTH_1 8 |
`define ETH_MIIRX_DATA_WIDTH 16 // not written from WB |
`define ETH_MIISTATUS_WIDTH 3 // not written from WB |
`define ETH_MAC_ADDR0_WIDTH_0 8 |
`define ETH_MAC_ADDR0_WIDTH_1 8 |
`define ETH_MAC_ADDR0_WIDTH_2 8 |
`define ETH_MAC_ADDR0_WIDTH_3 8 |
`define ETH_MAC_ADDR1_WIDTH_0 8 |
`define ETH_MAC_ADDR1_WIDTH_1 8 |
`define ETH_HASH0_WIDTH_0 8 |
`define ETH_HASH0_WIDTH_1 8 |
`define ETH_HASH0_WIDTH_2 8 |
`define ETH_HASH0_WIDTH_3 8 |
`define ETH_HASH1_WIDTH_0 8 |
`define ETH_HASH1_WIDTH_1 8 |
`define ETH_HASH1_WIDTH_2 8 |
`define ETH_HASH1_WIDTH_3 8 |
`define ETH_TX_CTRL_WIDTH_0 8 |
`define ETH_TX_CTRL_WIDTH_1 8 |
`define ETH_TX_CTRL_WIDTH_2 1 |
`define ETH_RX_CTRL_WIDTH_0 8 |
`define ETH_RX_CTRL_WIDTH_1 8 |
|
|
// Outputs are registered (uncomment when needed) |
`define ETH_REGISTERED_OUTPUTS |
|
// Settings for TX FIFO |
`define ETH_TX_FIFO_DATA_WIDTH 32 |
|
// Defines for ethernet TX fifo size - impacts FPGA resource usage |
|
//`define ETH_TX_64BYTE_FIFO // 64 byte TX buffer - uncomment this |
//`define ETH_TX_128BYTE_FIFO // 128 byte TX buffer - uncomment this |
`define ETH_TX_256BYTE_FIFO // 256 byte TX buffer - uncomment this |
//`define ETH_TX_512BYTE_FIFO // 512 byte TX buffer - uncomment this |
//`define ETH_TX_1KBYTE_FIFO // 1024 byte TX buffer - uncomment this |
//`define ETH_TX_FULL_PACKET_FIFO // Full 1500 byte TX buffer - uncomment this |
|
`ifdef ETH_TX_FULL_PACKET_FIFO |
`define ETH_TX_FIFO_CNT_WIDTH 9 |
`define ETH_TX_FIFO_DEPTH 375 |
`endif |
`ifdef ETH_TX_1KBYTE_FIFO |
`define ETH_TX_FIFO_CNT_WIDTH 8 |
`define ETH_TX_FIFO_DEPTH 256 |
`endif |
`ifdef ETH_TX_512BYTE_FIFO |
`define ETH_TX_FIFO_CNT_WIDTH 7 |
`define ETH_TX_FIFO_DEPTH 128 |
`endif |
`ifdef ETH_TX_256BYTE_FIFO |
`define ETH_TX_FIFO_CNT_WIDTH 6 |
`define ETH_TX_FIFO_DEPTH 64 |
`endif |
`ifdef ETH_TX_128BYTE_FIFO |
`define ETH_TX_FIFO_CNT_WIDTH 5 |
`define ETH_TX_FIFO_DEPTH 32 |
`endif |
`ifdef ETH_TX_128BYTE_FIFO |
`define ETH_TX_FIFO_CNT_WIDTH 4 |
`define ETH_TX_FIFO_DEPTH 16 |
`endif |
|
|
|
|
// Settings for RX FIFO |
//`define ETH_RX_FIFO_CNT_WIDTH 8 |
//`define ETH_RX_FIFO_DEPTH 256 |
//`define ETH_RX_FIFO_CNT_WIDTH 7 |
`define ETH_RX_FIFO_DEPTH 128 |
`define ETH_RX_FIFO_CNT_WIDTH 6 |
//`define ETH_RX_FIFO_DEPTH 64 |
//`define ETH_RX_FIFO_CNT_WIDTH 5 |
//`define ETH_RX_FIFO_DEPTH 32 |
//`define ETH_RX_FIFO_CNT_WIDTH 4 |
//`define ETH_RX_FIFO_DEPTH 16 |
|
`define ETH_RX_FIFO_DATA_WIDTH 32 |
|
// Burst length |
`define BURST_4BEAT |
`ifdef BURST_4BEAT |
`define ETH_BURST_LENGTH 4 // Change also ETH_BURST_CNT_WIDTH |
`define ETH_BURST_CNT_WIDTH 3 // The counter must be width enough to count to ETH_BURST_LENGTH |
`endif |
|
//`define ETH_BURST_LENGTH 32 // Change also ETH_BURST_CNT_WIDTH |
//`define ETH_BURST_CNT_WIDTH 7 // The counter must be width enough to count to ETH_BURST_LENGTH |
|
// Undefine this to enable bursting for RX (writing to memory) |
`define ETH_RX_BURST_EN |
|
// WISHBONE interface is Revision B3 compliant (uncomment when needed) |
`define ETH_WISHBONE_B3 |
|
// Hack where the transmit logic polls each of the TX buffers instead of having to keep track of what's going on |
//`define TXBD_POLL |
|
// Define this to allow reading of the Wishbone control state machine on reg |
// address 0x58 |
//`define WISHBONE_DEBUG |
/s3adsp1800/rtl/verilog/include/i2c_master_slave_defines.v
0,0 → 1,66
///////////////////////////////////////////////////////////////////// |
//// //// |
//// WISHBONE rev.B2 compliant I2C Master controller defines //// |
//// //// |
//// //// |
//// Author: Richard Herveille //// |
//// richard@asics.ws //// |
//// www.asics.ws //// |
//// //// |
//// Downloaded from: http://www.opencores.org/projects/i2c/ //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Richard Herveille //// |
//// richard@asics.ws //// |
//// //// |
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// |
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// |
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// |
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// |
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// |
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// |
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// |
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// |
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// |
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// |
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// |
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// |
//// POSSIBILITY OF SUCH DAMAGE. //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
|
// CVS Log |
// |
// $Id: i2c_master_defines.v,v 1.3 2001-11-05 11:59:25 rherveille Exp $ |
// |
// $Date: 2001-11-05 11:59:25 $ |
// $Revision: 1.3 $ |
// $Author: rherveille $ |
// $Locker: $ |
// $State: Exp $ |
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
|
|
// I2C registers wishbone addresses |
|
// bitcontroller states |
`define I2C_CMD_NOP 4'b0000 |
`define I2C_CMD_START 4'b0001 |
`define I2C_CMD_STOP 4'b0010 |
`define I2C_CMD_WRITE 4'b0100 |
`define I2C_CMD_READ 4'b1000 |
|
`define I2C_SLAVE_CMD_WRITE 2'b01 |
`define I2C_SLAVE_CMD_READ 2'b10 |
`define I2C_SLAVE_CMD_NOP 2'b00 |
|
|
|
/s3adsp1800/rtl/verilog/include/orpsoc-defines.v
0,0 → 1,88
////////////////////////////////////////////////////////////////////// |
//// //// |
//// orpsoc-defines //// |
//// //// |
//// Top level ORPSoC defines file //// |
//// //// |
//// Included in toplevel and testbench //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009, 2010 Authors and 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
`define XILINX |
`define XILINX_PLL |
`define FPGA_BOARD_XILINX_S3ADSP1800 |
`define IOCONFIG_XILINX_S3ADSP1800 |
`define BOARD_CLOCK_PERIOD 8000 // 125 MHz |
|
`define JTAG_DEBUG |
// `define RAM_WB |
`define XILINX_DDR2 |
`define UART0 |
`define GPIO0 |
`define SPI0 |
// `define I2C0 |
`define ETH0 |
`define ETH0_PHY_RST |
|
// end of included module defines - keep this comment line here, scripts depend on it!! |
|
|
// |
// Arbiter defines |
// |
|
// Uncomment to register things through arbiter (hopefully quicker design) |
// Instruction bus arbiter |
//`define ARBITER_IBUS_REGISTERING |
`define ARBITER_IBUS_WATCHDOG |
// Watchdog timeout: 2^(ARBITER_IBUS_WATCHDOG_TIMER_WIDTH+1) cycles |
// This has to be kind of long, as DDR2 initialisation can take a little while |
// and after reset, and if this is too short we'll always get bus error. |
`ifdef XILINX_DDR2 |
`define ARBITER_IBUS_WATCHDOG_TIMER_WIDTH 20 |
`else |
`define ARBITER_IBUS_WATCHDOG_TIMER_WIDTH 6 |
`endif |
|
// Data bus arbiter |
|
//`define ARBITER_DBUS_REGISTERING |
`define ARBITER_DBUS_WATCHDOG |
// Watchdog timeout: 2^(ARBITER_DBUS_WATCHDOG_TIMER_WIDTH+1) cycles |
`ifdef XILINX_DDR2 |
`define ARBITER_DBUS_WATCHDOG_TIMER_WIDTH 20 |
`else |
`define ARBITER_DBUS_WATCHDOG_TIMER_WIDTH 6 |
`endif |
|
// Byte bus (peripheral bus) arbiter |
// Don't really need the watchdog here - the databus will pick it up |
//`define ARBITER_BYTEBUS_WATCHDOG |
// Watchdog timeout: 2^(ARBITER_BYTEBUS_WATCHDOG_TIMER_WIDTH+1) cycles |
`define ARBITER_BYTEBUS_WATCHDOG_TIMER_WIDTH 9 |
|
/s3adsp1800/rtl/verilog/include/dbg_cpu_defines.v
0,0 → 1,85
////////////////////////////////////////////////////////////////////// |
//// //// |
//// dbg_cpu_defines.v //// |
//// //// |
//// //// |
//// This file is part of the SoC Debug Interface. //// |
//// http://www.opencores.org/projects/DebugInterface/ //// |
//// //// |
//// Author(s): //// |
//// Igor Mohor (igorm@opencores.org) //// |
//// //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 - 2004 Authors //// |
//// //// |
//// 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
// Defining length of the command |
`define DBG_CPU_CMD_LEN 3'd4 |
`define DBG_CPU_CMD_CNT_WIDTH 3 |
|
// Defining length of the access_type field |
`define DBG_CPU_ACC_TYPE_LEN 4 |
|
// Defining length of the address |
`define DBG_CPU_ADR_LEN 32 |
|
// Defining length of the length register |
`define DBG_CPU_LEN_LEN 16 |
|
// Defining total length of the DR needed |
`define DBG_CPU_DR_LEN (`DBG_CPU_ACC_TYPE_LEN + `DBG_CPU_ADR_LEN + `DBG_CPU_LEN_LEN) |
// Defining length of the CRC |
`define DBG_CPU_CRC_LEN 6'd32 |
`define DBG_CPU_CRC_CNT_WIDTH 6 |
|
// Defining length of status |
`define DBG_CPU_STATUS_LEN 3'd4 |
`define DBG_CPU_STATUS_CNT_WIDTH 3 |
|
// Defining length of the data |
//define DBG_CPU_DATA_CNT_WIDTH `DBG_CPU_LEN_LEN + 3 |
`define DBG_CPU_DATA_CNT_WIDTH 19 |
//define DBG_CPU_DATA_CNT_LIM_WIDTH `DBG_CPU_LEN_LEN |
`define DBG_CPU_DATA_CNT_LIM_WIDTH 16 |
// Defining length of the control register |
`define DBG_CPU_CTRL_LEN 2 |
|
//Defining commands |
`define DBG_CPU_GO 4'h0 |
`define DBG_CPU_RD_COMM 4'h1 |
`define DBG_CPU_WR_COMM 4'h2 |
`define DBG_CPU_RD_CTRL 4'h3 |
`define DBG_CPU_WR_CTRL 4'h4 |
|
// Defining access types for wishbone |
`define DBG_CPU_WRITE 4'h2 |
`define DBG_CPU_READ 4'h6 |
|
|
/s3adsp1800/rtl/verilog/include/or1200_defines.v
0,0 → 1,1822
////////////////////////////////////////////////////////////////////// |
//// //// |
//// OR1200's definitions //// |
//// //// |
//// This file is part of the OpenRISC 1200 project //// |
//// http://opencores.org/project,or1k //// |
//// //// |
//// Description //// |
//// Defines for the OR1200 core //// |
//// //// |
//// To Do: //// |
//// - add parameters that are missing //// |
//// //// |
//// Author(s): //// |
//// - Damjan Lampret, lampret@opencores.org //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Authors and 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// $Log: or1200_defines.v,v $ |
// Revision 2.0 2010/06/30 11:00:00 ORSoC |
// Minor update: |
// Defines added, bugs fixed. |
|
// |
// Dump VCD |
// |
//`define OR1200_VCD_DUMP |
|
// |
// Generate debug messages during simulation |
// |
//`define OR1200_VERBOSE |
|
// `define OR1200_ASIC |
//////////////////////////////////////////////////////// |
// |
// Typical configuration for an ASIC |
// |
`ifdef OR1200_ASIC |
|
// |
// Target ASIC memories |
// |
//`define OR1200_ARTISAN_SSP |
//`define OR1200_ARTISAN_SDP |
//`define OR1200_ARTISAN_STP |
`define OR1200_VIRTUALSILICON_SSP |
//`define OR1200_VIRTUALSILICON_STP_T1 |
//`define OR1200_VIRTUALSILICON_STP_T2 |
|
// |
// Do not implement Data cache |
// |
//`define OR1200_NO_DC |
|
// |
// Do not implement Insn cache |
// |
//`define OR1200_NO_IC |
|
// |
// Do not implement Data MMU |
// |
//`define OR1200_NO_DMMU |
|
// |
// Do not implement Insn MMU |
// |
//`define OR1200_NO_IMMU |
|
// |
// Select between ASIC optimized and generic multiplier |
// |
//`define OR1200_ASIC_MULTP2_32X32 |
`define OR1200_GENERIC_MULTP2_32X32 |
|
// |
// Size/type of insn/data cache if implemented |
// |
// `define OR1200_IC_1W_512B |
// `define OR1200_IC_1W_4KB |
`define OR1200_IC_1W_8KB |
// `define OR1200_DC_1W_4KB |
`define OR1200_DC_1W_8KB |
|
`else |
|
|
///////////////////////////////////////////////////////// |
// |
// Typical configuration for an FPGA |
// |
|
// |
// Target FPGA memories |
// |
//`define OR1200_ALTERA_LPM |
//`define OR1200_XILINX_RAMB16 |
//`define OR1200_XILINX_RAMB4 |
//`define OR1200_XILINX_RAM32X1D |
//`define OR1200_USE_RAM16X1D_FOR_RAM32X1D |
// Generic models should infer RAM blocks at synthesis time (not only effects |
// single port ram.) |
`define OR1200_GENERIC |
|
// |
// Do not implement Data cache |
// |
//`define OR1200_NO_DC |
|
// |
// Do not implement Insn cache |
// |
//`define OR1200_NO_IC |
|
// |
// Do not implement Data MMU |
// |
//`define OR1200_NO_DMMU |
|
// |
// Do not implement Insn MMU |
// |
//`define OR1200_NO_IMMU |
|
// |
// Select between ASIC and generic multiplier |
// |
// (Generic seems to trigger a bug in the Cadence Ncsim simulator) |
// |
//`define OR1200_ASIC_MULTP2_32X32 |
`define OR1200_GENERIC_MULTP2_32X32 |
|
// |
// Size/type of insn/data cache if implemented |
// (consider available FPGA memory resources) |
// |
`define OR1200_IC_1W_512B |
//`define OR1200_IC_1W_4KB |
//`define OR1200_IC_1W_8KB |
//`define OR1200_IC_1W_16KB |
//`define OR1200_IC_1W_32KB |
`define OR1200_DC_1W_4KB |
//`define OR1200_DC_1W_8KB |
//`define OR1200_DC_1W_16KB |
//`define OR1200_DC_1W_32KB |
|
`endif |
|
|
////////////////////////////////////////////////////////// |
// |
// Do not change below unless you know what you are doing |
// |
|
// |
// Reset active low |
// |
//`define OR1200_RST_ACT_LOW |
|
// |
// Enable RAM BIST |
// |
// At the moment this only works for Virtual Silicon |
// single port RAMs. For other RAMs it has not effect. |
// Special wrapper for VS RAMs needs to be provided |
// with scan flops to facilitate bist scan. |
// |
//`define OR1200_BIST |
|
// |
// Register OR1200 WISHBONE outputs |
// (must be defined/enabled) |
// |
`define OR1200_REGISTERED_OUTPUTS |
|
// |
// Register OR1200 WISHBONE inputs |
// |
// (must be undefined/disabled) |
// |
//`define OR1200_REGISTERED_INPUTS |
|
// |
// Disable bursts if they are not supported by the |
// memory subsystem (only affect cache line fill) |
// |
//`define OR1200_NO_BURSTS |
// |
|
// |
// WISHBONE retry counter range |
// |
// 2^value range for retry counter. Retry counter |
// is activated whenever *wb_rty_i is asserted and |
// until retry counter expires, corresponding |
// WISHBONE interface is deactivated. |
// |
// To disable retry counters and *wb_rty_i all together, |
// undefine this macro. |
// |
//`define OR1200_WB_RETRY 7 |
|
// |
// WISHBONE Consecutive Address Burst |
// |
// This was used prior to WISHBONE B3 specification |
// to identify bursts. It is no longer needed but |
// remains enabled for compatibility with old designs. |
// |
// To remove *wb_cab_o ports undefine this macro. |
// |
//`define OR1200_WB_CAB |
|
// |
// WISHBONE B3 compatible interface |
// |
// This follows the WISHBONE B3 specification. |
// It is not enabled by default because most |
// designs still don't use WB b3. |
// |
// To enable *wb_cti_o/*wb_bte_o ports, |
// define this macro. |
// |
`define OR1200_WB_B3 |
|
// |
// LOG all WISHBONE accesses |
// |
`define OR1200_LOG_WB_ACCESS |
|
// |
// Enable additional synthesis directives if using |
// _Synopsys_ synthesis tool |
// |
//`define OR1200_ADDITIONAL_SYNOPSYS_DIRECTIVES |
|
// |
// Enables default statement in some case blocks |
// and disables Synopsys synthesis directive full_case |
// |
// By default it is enabled. When disabled it |
// can increase clock frequency. |
// |
`define OR1200_CASE_DEFAULT |
|
// |
// Operand width / register file address width |
// |
// (DO NOT CHANGE) |
// |
`define OR1200_OPERAND_WIDTH 32 |
`define OR1200_REGFILE_ADDR_WIDTH 5 |
|
// |
// l.add/l.addi/l.and and optional l.addc/l.addic |
// also set (compare) flag when result of their |
// operation equals zero |
// |
// At the time of writing this, default or32 |
// C/C++ compiler doesn't generate code that |
// would benefit from this optimization. |
// |
// By default this optimization is disabled to |
// save area. |
// |
//`define OR1200_ADDITIONAL_FLAG_MODIFIERS |
|
// |
// Implement l.addc/l.addic instructions |
// |
// By default implementation of l.addc/l.addic |
// instructions is enabled in case you need them. |
// If you don't use them, then disable implementation |
// to save area. |
// |
//`define OR1200_IMPL_ADDC |
|
// |
// Implement l.sub instruction |
// |
// By default implementation of l.sub instructions |
// is enabled to be compliant with the simulator. |
// If you don't use carry bit, then disable |
// implementation to save area. |
// |
`define OR1200_IMPL_SUB |
|
// |
// Implement carry bit SR[CY] |
// |
// |
// By default implementation of SR[CY] is enabled |
// to be compliant with the simulator. However SR[CY] |
// is explicitly only used by l.addc/l.addic/l.sub |
// instructions and if these three insns are not |
// implemented there is not much point having SR[CY]. |
// |
//`define OR1200_IMPL_CY |
|
// |
// Implement carry bit SR[OV] |
// |
// Compiler doesn't use this, but other code may like |
// to. |
// |
//`define OR1200_IMPL_OV |
|
// |
// Implement carry bit SR[OVE] |
// |
// Overflow interrupt indicator. When enabled, SR[OV] flag |
// does not remain asserted after exception. |
// |
//`define OR1200_IMPL_OVE |
|
|
// |
// Implement rotate in the ALU |
// |
// At the time of writing this, or32 |
// C/C++ compiler doesn't generate rotate |
// instructions. However or32 assembler |
// can assemble code that uses rotate insn. |
// This means that rotate instructions |
// must be used manually inserted. |
// |
// By default implementation of rotate |
// is disabled to save area and increase |
// clock frequency. |
// |
//`define OR1200_IMPL_ALU_ROTATE |
|
// |
// Type of ALU compare to implement |
// |
// Try either one to find what yields |
// higher clock frequencyin your case. |
// |
//`define OR1200_IMPL_ALU_COMP1 |
`define OR1200_IMPL_ALU_COMP2 |
|
// |
// Implement Find First/Last '1' |
// |
`define OR1200_IMPL_ALU_FFL1 |
|
// |
// Implement l.cust5 ALU instruction |
// |
//`define OR1200_IMPL_ALU_CUST5 |
|
// |
// Implement l.extXs and l.extXz instructions |
// |
//`define OR1200_IMPL_ALU_EXT |
|
// |
// Implement multiplier |
// |
// By default multiplier is implemented |
// |
`define OR1200_MULT_IMPLEMENTED |
|
// |
// Implement multiply-and-accumulate |
// |
// By default MAC is implemented. To |
// implement MAC, multiplier (non-serial) needs to be |
// implemented. |
// |
`define OR1200_MAC_IMPLEMENTED |
|
// |
// Implement optional l.div/l.divu instructions |
// |
// By default divide instructions are not implemented |
// to save area. |
// |
// |
`define OR1200_DIV_IMPLEMENTED |
|
// |
// Serial multiplier. |
// |
//`define OR1200_MULT_SERIAL |
|
// |
// Serial divider. |
// Uncomment to use a serial divider, otherwise will |
// be a generic parallel implementation. |
// |
`define OR1200_DIV_SERIAL |
|
// |
// Implement HW Single Precision FPU |
// |
//`define OR1200_FPU_IMPLEMENTED |
|
// |
// Clock ratio RISC clock versus WB clock |
// |
// If you plan to run WB:RISC clock fixed to 1:1, disable |
// both defines |
// |
// For WB:RISC 1:2 or 1:1, enable OR1200_CLKDIV_2_SUPPORTED |
// and use clmode to set ratio |
// |
// For WB:RISC 1:4, 1:2 or 1:1, enable both defines and use |
// clmode to set ratio |
// |
//`define OR1200_CLKDIV_2_SUPPORTED |
//`define OR1200_CLKDIV_4_SUPPORTED |
|
// |
// Type of register file RAM |
// |
// Memory macro w/ two ports (see or1200_tpram_32x32.v) |
//`define OR1200_RFRAM_TWOPORT |
// |
// Memory macro dual port (see or1200_dpram.v) |
`define OR1200_RFRAM_DUALPORT |
|
// |
// Generic (flip-flop based) register file (see or1200_rfram_generic.v) |
//`define OR1200_RFRAM_GENERIC |
// Generic register file supports - 16 registers |
`ifdef OR1200_RFRAM_GENERIC |
// `define OR1200_RFRAM_16REG |
`endif |
|
// |
// Type of mem2reg aligner to implement. |
// |
// Once OR1200_IMPL_MEM2REG2 yielded faster |
// circuit, however with today tools it will |
// most probably give you slower circuit. |
// |
`define OR1200_IMPL_MEM2REG1 |
//`define OR1200_IMPL_MEM2REG2 |
|
// |
// Reset value and event |
// |
`ifdef OR1200_RST_ACT_LOW |
`define OR1200_RST_VALUE (1'b0) |
`define OR1200_RST_EVENT negedge |
`else |
`define OR1200_RST_VALUE (1'b1) |
`define OR1200_RST_EVENT posedge |
`endif |
|
// |
// ALUOPs |
// |
`define OR1200_ALUOP_WIDTH 5 |
`define OR1200_ALUOP_NOP 5'b0_0100 |
/* LS-nibble encodings correspond to bits [3:0] of instruction */ |
`define OR1200_ALUOP_ADD 5'b0_0000 // 0 |
`define OR1200_ALUOP_ADDC 5'b0_0001 // 1 |
`define OR1200_ALUOP_SUB 5'b0_0010 // 2 |
`define OR1200_ALUOP_AND 5'b0_0011 // 3 |
`define OR1200_ALUOP_OR 5'b0_0100 // 4 |
`define OR1200_ALUOP_XOR 5'b0_0101 // 5 |
`define OR1200_ALUOP_MUL 5'b0_0110 // 6 |
`define OR1200_ALUOP_RESERVED 5'b0_0111 // 7 |
`define OR1200_ALUOP_SHROT 5'b0_1000 // 8 |
`define OR1200_ALUOP_DIV 5'b0_1001 // 9 |
`define OR1200_ALUOP_DIVU 5'b0_1010 // a |
`define OR1200_ALUOP_MULU 5'b0_1011 // b |
`define OR1200_ALUOP_EXTHB 5'b0_1100 // c |
`define OR1200_ALUOP_EXTW 5'b0_1101 // d |
`define OR1200_ALUOP_CMOV 5'b0_1110 // e |
`define OR1200_ALUOP_FFL1 5'b0_1111 // f |
|
/* Values sent to ALU from decode unit - not defined by ISA */ |
`define OR1200_ALUOP_COMP 5'b1_0000 // Comparison |
`define OR1200_ALUOP_MOVHI 5'b1_0001 // Move-high |
`define OR1200_ALUOP_CUST5 5'b1_0010 // l.cust5 |
|
// ALU instructions second opcode field |
`define OR1200_ALUOP2_POS 9:6 |
`define OR1200_ALUOP2_WIDTH 4 |
|
// |
// MACOPs |
// |
`define OR1200_MACOP_WIDTH 3 |
`define OR1200_MACOP_NOP 3'b000 |
`define OR1200_MACOP_MAC 3'b001 |
`define OR1200_MACOP_MSB 3'b010 |
|
// |
// Shift/rotate ops |
// |
`define OR1200_SHROTOP_WIDTH 4 |
`define OR1200_SHROTOP_NOP 4'd0 |
`define OR1200_SHROTOP_SLL 4'd0 |
`define OR1200_SHROTOP_SRL 4'd1 |
`define OR1200_SHROTOP_SRA 4'd2 |
`define OR1200_SHROTOP_ROR 4'd3 |
|
// |
// Zero/Sign Extend ops |
// |
`define OR1200_EXTHBOP_WIDTH 4 |
`define OR1200_EXTHBOP_BS 4'h1 |
`define OR1200_EXTHBOP_HS 4'h0 |
`define OR1200_EXTHBOP_BZ 4'h3 |
`define OR1200_EXTHBOP_HZ 4'h2 |
`define OR1200_EXTWOP_WIDTH 4 |
`define OR1200_EXTWOP_WS 4'h0 |
`define OR1200_EXTWOP_WZ 4'h1 |
|
// Execution cycles per instruction |
`define OR1200_MULTICYCLE_WIDTH 3 |
`define OR1200_ONE_CYCLE 3'd0 |
`define OR1200_TWO_CYCLES 3'd1 |
|
// Execution control which will "wait on" a module to finish |
`define OR1200_WAIT_ON_WIDTH 2 |
`define OR1200_WAIT_ON_NOTHING `OR1200_WAIT_ON_WIDTH'd0 |
`define OR1200_WAIT_ON_MULTMAC `OR1200_WAIT_ON_WIDTH'd1 |
`define OR1200_WAIT_ON_FPU `OR1200_WAIT_ON_WIDTH'd2 |
`define OR1200_WAIT_ON_MTSPR `OR1200_WAIT_ON_WIDTH'd3 |
|
|
// Operand MUX selects |
`define OR1200_SEL_WIDTH 2 |
`define OR1200_SEL_RF 2'd0 |
`define OR1200_SEL_IMM 2'd1 |
`define OR1200_SEL_EX_FORW 2'd2 |
`define OR1200_SEL_WB_FORW 2'd3 |
|
// |
// BRANCHOPs |
// |
`define OR1200_BRANCHOP_WIDTH 3 |
`define OR1200_BRANCHOP_NOP 3'd0 |
`define OR1200_BRANCHOP_J 3'd1 |
`define OR1200_BRANCHOP_JR 3'd2 |
`define OR1200_BRANCHOP_BAL 3'd3 |
`define OR1200_BRANCHOP_BF 3'd4 |
`define OR1200_BRANCHOP_BNF 3'd5 |
`define OR1200_BRANCHOP_RFE 3'd6 |
|
// |
// LSUOPs |
// |
// Bit 0: sign extend |
// Bits 1-2: 00 doubleword, 01 byte, 10 halfword, 11 singleword |
// Bit 3: 0 load, 1 store |
`define OR1200_LSUOP_WIDTH 4 |
`define OR1200_LSUOP_NOP 4'b0000 |
`define OR1200_LSUOP_LBZ 4'b0010 |
`define OR1200_LSUOP_LBS 4'b0011 |
`define OR1200_LSUOP_LHZ 4'b0100 |
`define OR1200_LSUOP_LHS 4'b0101 |
`define OR1200_LSUOP_LWZ 4'b0110 |
`define OR1200_LSUOP_LWS 4'b0111 |
`define OR1200_LSUOP_LD 4'b0001 |
`define OR1200_LSUOP_SD 4'b1000 |
`define OR1200_LSUOP_SB 4'b1010 |
`define OR1200_LSUOP_SH 4'b1100 |
`define OR1200_LSUOP_SW 4'b1110 |
|
// Number of bits of load/store EA precalculated in ID stage |
// for balancing ID and EX stages. |
// |
// Valid range: 2,3,...,30,31 |
`define OR1200_LSUEA_PRECALC 2 |
|
// FETCHOPs |
`define OR1200_FETCHOP_WIDTH 1 |
`define OR1200_FETCHOP_NOP 1'b0 |
`define OR1200_FETCHOP_LW 1'b1 |
|
// |
// Register File Write-Back OPs |
// |
// Bit 0: register file write enable |
// Bits 3-1: write-back mux selects |
// |
`define OR1200_RFWBOP_WIDTH 4 |
`define OR1200_RFWBOP_NOP 4'b0000 |
`define OR1200_RFWBOP_ALU 3'b000 |
`define OR1200_RFWBOP_LSU 3'b001 |
`define OR1200_RFWBOP_SPRS 3'b010 |
`define OR1200_RFWBOP_LR 3'b011 |
`define OR1200_RFWBOP_FPU 3'b100 |
|
// Compare instructions |
`define OR1200_COP_SFEQ 3'b000 |
`define OR1200_COP_SFNE 3'b001 |
`define OR1200_COP_SFGT 3'b010 |
`define OR1200_COP_SFGE 3'b011 |
`define OR1200_COP_SFLT 3'b100 |
`define OR1200_COP_SFLE 3'b101 |
`define OR1200_COP_X 3'b111 |
`define OR1200_SIGNED_COMPARE 'd3 |
`define OR1200_COMPOP_WIDTH 4 |
|
// |
// FP OPs |
// |
// MSbit indicates FPU operation valid |
// |
`define OR1200_FPUOP_WIDTH 8 |
// FPU unit from Usselman takes 5 cycles from decode, so 4 ex. cycles |
`define OR1200_FPUOP_CYCLES 3'd4 |
// FP instruction is double precision if bit 4 is set. We're a 32-bit |
// implementation thus do not support double precision FP |
`define OR1200_FPUOP_DOUBLE_BIT 4 |
`define OR1200_FPUOP_ADD 8'b0000_0000 |
`define OR1200_FPUOP_SUB 8'b0000_0001 |
`define OR1200_FPUOP_MUL 8'b0000_0010 |
`define OR1200_FPUOP_DIV 8'b0000_0011 |
`define OR1200_FPUOP_ITOF 8'b0000_0100 |
`define OR1200_FPUOP_FTOI 8'b0000_0101 |
`define OR1200_FPUOP_REM 8'b0000_0110 |
`define OR1200_FPUOP_RESERVED 8'b0000_0111 |
// FP Compare instructions |
`define OR1200_FPCOP_SFEQ 8'b0000_1000 |
`define OR1200_FPCOP_SFNE 8'b0000_1001 |
`define OR1200_FPCOP_SFGT 8'b0000_1010 |
`define OR1200_FPCOP_SFGE 8'b0000_1011 |
`define OR1200_FPCOP_SFLT 8'b0000_1100 |
`define OR1200_FPCOP_SFLE 8'b0000_1101 |
|
// |
// TAGs for instruction bus |
// |
`define OR1200_ITAG_IDLE 4'h0 // idle bus |
`define OR1200_ITAG_NI 4'h1 // normal insn |
`define OR1200_ITAG_BE 4'hb // Bus error exception |
`define OR1200_ITAG_PE 4'hc // Page fault exception |
`define OR1200_ITAG_TE 4'hd // TLB miss exception |
|
// |
// TAGs for data bus |
// |
`define OR1200_DTAG_IDLE 4'h0 // idle bus |
`define OR1200_DTAG_ND 4'h1 // normal data |
`define OR1200_DTAG_AE 4'ha // Alignment exception |
`define OR1200_DTAG_BE 4'hb // Bus error exception |
`define OR1200_DTAG_PE 4'hc // Page fault exception |
`define OR1200_DTAG_TE 4'hd // TLB miss exception |
|
|
////////////////////////////////////////////// |
// |
// ORBIS32 ISA specifics |
// |
|
// SHROT_OP position in machine word |
`define OR1200_SHROTOP_POS 7:6 |
|
// |
// Instruction opcode groups (basic) |
// |
`define OR1200_OR32_J 6'b000000 |
`define OR1200_OR32_JAL 6'b000001 |
`define OR1200_OR32_BNF 6'b000011 |
`define OR1200_OR32_BF 6'b000100 |
`define OR1200_OR32_NOP 6'b000101 |
`define OR1200_OR32_MOVHI 6'b000110 |
`define OR1200_OR32_MACRC 6'b000110 |
`define OR1200_OR32_XSYNC 6'b001000 |
`define OR1200_OR32_RFE 6'b001001 |
/* */ |
`define OR1200_OR32_JR 6'b010001 |
`define OR1200_OR32_JALR 6'b010010 |
`define OR1200_OR32_MACI 6'b010011 |
/* */ |
`define OR1200_OR32_LWZ 6'b100001 |
`define OR1200_OR32_LBZ 6'b100011 |
`define OR1200_OR32_LBS 6'b100100 |
`define OR1200_OR32_LHZ 6'b100101 |
`define OR1200_OR32_LHS 6'b100110 |
`define OR1200_OR32_ADDI 6'b100111 |
`define OR1200_OR32_ADDIC 6'b101000 |
`define OR1200_OR32_ANDI 6'b101001 |
`define OR1200_OR32_ORI 6'b101010 |
`define OR1200_OR32_XORI 6'b101011 |
`define OR1200_OR32_MULI 6'b101100 |
`define OR1200_OR32_MFSPR 6'b101101 |
`define OR1200_OR32_SH_ROTI 6'b101110 |
`define OR1200_OR32_SFXXI 6'b101111 |
/* */ |
`define OR1200_OR32_MTSPR 6'b110000 |
`define OR1200_OR32_MACMSB 6'b110001 |
`define OR1200_OR32_FLOAT 6'b110010 |
/* */ |
`define OR1200_OR32_SW 6'b110101 |
`define OR1200_OR32_SB 6'b110110 |
`define OR1200_OR32_SH 6'b110111 |
`define OR1200_OR32_ALU 6'b111000 |
`define OR1200_OR32_SFXX 6'b111001 |
`define OR1200_OR32_CUST5 6'b111100 |
|
///////////////////////////////////////////////////// |
// |
// Exceptions |
// |
|
// |
// Exception vectors per OR1K architecture: |
// 0xPPPPP100 - reset |
// 0xPPPPP200 - bus error |
// ... etc |
// where P represents exception prefix. |
// |
// Exception vectors can be customized as per |
// the following formula: |
// 0xPPPPPNVV - exception N |
// |
// P represents exception prefix |
// N represents exception N |
// VV represents length of the individual vector space, |
// usually it is 8 bits wide and starts with all bits zero |
// |
|
// |
// PPPPP and VV parts |
// |
// Sum of these two defines needs to be 28 |
// |
`define OR1200_EXCEPT_EPH0_P 20'h00000 |
`define OR1200_EXCEPT_EPH1_P 20'hF0000 |
`define OR1200_EXCEPT_V 8'h00 |
|
// |
// N part width |
// |
`define OR1200_EXCEPT_WIDTH 4 |
|
// |
// Definition of exception vectors |
// |
// To avoid implementation of a certain exception, |
// simply comment out corresponding line |
// |
`define OR1200_EXCEPT_UNUSED `OR1200_EXCEPT_WIDTH'hf |
`define OR1200_EXCEPT_TRAP `OR1200_EXCEPT_WIDTH'he |
`define OR1200_EXCEPT_FLOAT `OR1200_EXCEPT_WIDTH'hd |
`define OR1200_EXCEPT_SYSCALL `OR1200_EXCEPT_WIDTH'hc |
`define OR1200_EXCEPT_RANGE `OR1200_EXCEPT_WIDTH'hb |
`define OR1200_EXCEPT_ITLBMISS `OR1200_EXCEPT_WIDTH'ha |
`define OR1200_EXCEPT_DTLBMISS `OR1200_EXCEPT_WIDTH'h9 |
`define OR1200_EXCEPT_INT `OR1200_EXCEPT_WIDTH'h8 |
`define OR1200_EXCEPT_ILLEGAL `OR1200_EXCEPT_WIDTH'h7 |
`define OR1200_EXCEPT_ALIGN `OR1200_EXCEPT_WIDTH'h6 |
`define OR1200_EXCEPT_TICK `OR1200_EXCEPT_WIDTH'h5 |
`define OR1200_EXCEPT_IPF `OR1200_EXCEPT_WIDTH'h4 |
`define OR1200_EXCEPT_DPF `OR1200_EXCEPT_WIDTH'h3 |
`define OR1200_EXCEPT_BUSERR `OR1200_EXCEPT_WIDTH'h2 |
`define OR1200_EXCEPT_RESET `OR1200_EXCEPT_WIDTH'h1 |
`define OR1200_EXCEPT_NONE `OR1200_EXCEPT_WIDTH'h0 |
|
|
///////////////////////////////////////////////////// |
// |
// SPR groups |
// |
|
// Bits that define the group |
`define OR1200_SPR_GROUP_BITS 15:11 |
|
// Width of the group bits |
`define OR1200_SPR_GROUP_WIDTH 5 |
|
// Bits that define offset inside the group |
`define OR1200_SPR_OFS_BITS 10:0 |
|
// List of groups |
`define OR1200_SPR_GROUP_SYS 5'd00 |
`define OR1200_SPR_GROUP_DMMU 5'd01 |
`define OR1200_SPR_GROUP_IMMU 5'd02 |
`define OR1200_SPR_GROUP_DC 5'd03 |
`define OR1200_SPR_GROUP_IC 5'd04 |
`define OR1200_SPR_GROUP_MAC 5'd05 |
`define OR1200_SPR_GROUP_DU 5'd06 |
`define OR1200_SPR_GROUP_PM 5'd08 |
`define OR1200_SPR_GROUP_PIC 5'd09 |
`define OR1200_SPR_GROUP_TT 5'd10 |
`define OR1200_SPR_GROUP_FPU 5'd11 |
|
///////////////////////////////////////////////////// |
// |
// System group |
// |
|
// |
// System registers |
// |
`define OR1200_SPR_CFGR 7'd0 |
`define OR1200_SPR_RF 6'd32 // 1024 >> 5 |
`define OR1200_SPR_NPC 11'd16 |
`define OR1200_SPR_SR 11'd17 |
`define OR1200_SPR_PPC 11'd18 |
`define OR1200_SPR_FPCSR 11'd20 |
`define OR1200_SPR_EPCR 11'd32 |
`define OR1200_SPR_EEAR 11'd48 |
`define OR1200_SPR_ESR 11'd64 |
|
// |
// SR bits |
// |
`define OR1200_SR_WIDTH 17 |
`define OR1200_SR_SM 0 |
`define OR1200_SR_TEE 1 |
`define OR1200_SR_IEE 2 |
`define OR1200_SR_DCE 3 |
`define OR1200_SR_ICE 4 |
`define OR1200_SR_DME 5 |
`define OR1200_SR_IME 6 |
`define OR1200_SR_LEE 7 |
`define OR1200_SR_CE 8 |
`define OR1200_SR_F 9 |
`define OR1200_SR_CY 10 // Optional |
`define OR1200_SR_OV 11 // Optional |
`define OR1200_SR_OVE 12 // Optional |
`define OR1200_SR_DSX 13 // Unused |
`define OR1200_SR_EPH 14 |
`define OR1200_SR_FO 15 |
`define OR1200_SR_TED 16 |
`define OR1200_SR_CID 31:28 // Unimplemented |
|
// |
// Bits that define offset inside the group |
// |
`define OR1200_SPROFS_BITS 10:0 |
|
// |
// Default Exception Prefix |
// |
// 1'b0 - OR1200_EXCEPT_EPH0_P (0x0000_0000) |
// 1'b1 - OR1200_EXCEPT_EPH1_P (0xF000_0000) |
// |
`define OR1200_SR_EPH_DEF 1'b0 |
|
|
// |
// FPCSR bits |
// |
`define OR1200_FPCSR_WIDTH 12 |
`define OR1200_FPCSR_FPEE 0 |
`define OR1200_FPCSR_RM 2:1 |
`define OR1200_FPCSR_OVF 3 |
`define OR1200_FPCSR_UNF 4 |
`define OR1200_FPCSR_SNF 5 |
`define OR1200_FPCSR_QNF 6 |
`define OR1200_FPCSR_ZF 7 |
`define OR1200_FPCSR_IXF 8 |
`define OR1200_FPCSR_IVF 9 |
`define OR1200_FPCSR_INF 10 |
`define OR1200_FPCSR_DZF 11 |
`define OR1200_FPCSR_RES 31:12 |
|
///////////////////////////////////////////////////// |
// |
// Power Management (PM) |
// |
|
// Define it if you want PM implemented |
//`define OR1200_PM_IMPLEMENTED |
|
// Bit positions inside PMR (don't change) |
`define OR1200_PM_PMR_SDF 3:0 |
`define OR1200_PM_PMR_DME 4 |
`define OR1200_PM_PMR_SME 5 |
`define OR1200_PM_PMR_DCGE 6 |
`define OR1200_PM_PMR_UNUSED 31:7 |
|
// PMR offset inside PM group of registers |
`define OR1200_PM_OFS_PMR 11'b0 |
|
// PM group |
`define OR1200_SPRGRP_PM 5'd8 |
|
// Define if PMR can be read/written at any address inside PM group |
`define OR1200_PM_PARTIAL_DECODING |
|
// Define if reading PMR is allowed |
`define OR1200_PM_READREGS |
|
// Define if unused PMR bits should be zero |
`define OR1200_PM_UNUSED_ZERO |
|
|
///////////////////////////////////////////////////// |
// |
// Debug Unit (DU) |
// |
|
// Define it if you want DU implemented |
`define OR1200_DU_IMPLEMENTED |
|
// |
// Define if you want HW Breakpoints |
// (if HW breakpoints are not implemented |
// only default software trapping is |
// possible with l.trap insn - this is |
// however already enough for use |
// with or32 gdb) |
// |
//`define OR1200_DU_HWBKPTS |
|
// Number of DVR/DCR pairs if HW breakpoints enabled |
// Comment / uncomment DU_DVRn / DU_DCRn pairs bellow according to this number ! |
// DU_DVR0..DU_DVR7 should be uncommented for 8 DU_DVRDCR_PAIRS |
`define OR1200_DU_DVRDCR_PAIRS 8 |
|
// Define if you want trace buffer |
// (for now only available for Xilinx Virtex FPGAs) |
//`define OR1200_DU_TB_IMPLEMENTED |
|
|
// |
// Address offsets of DU registers inside DU group |
// |
// To not implement a register, doq not define its address |
// |
`ifdef OR1200_DU_HWBKPTS |
`define OR1200_DU_DVR0 11'd0 |
`define OR1200_DU_DVR1 11'd1 |
`define OR1200_DU_DVR2 11'd2 |
`define OR1200_DU_DVR3 11'd3 |
`define OR1200_DU_DVR4 11'd4 |
`define OR1200_DU_DVR5 11'd5 |
`define OR1200_DU_DVR6 11'd6 |
`define OR1200_DU_DVR7 11'd7 |
`define OR1200_DU_DCR0 11'd8 |
`define OR1200_DU_DCR1 11'd9 |
`define OR1200_DU_DCR2 11'd10 |
`define OR1200_DU_DCR3 11'd11 |
`define OR1200_DU_DCR4 11'd12 |
`define OR1200_DU_DCR5 11'd13 |
`define OR1200_DU_DCR6 11'd14 |
`define OR1200_DU_DCR7 11'd15 |
`endif |
`define OR1200_DU_DMR1 11'd16 |
`ifdef OR1200_DU_HWBKPTS |
`define OR1200_DU_DMR2 11'd17 |
`define OR1200_DU_DWCR0 11'd18 |
`define OR1200_DU_DWCR1 11'd19 |
`endif |
`define OR1200_DU_DSR 11'd20 |
`define OR1200_DU_DRR 11'd21 |
`ifdef OR1200_DU_TB_IMPLEMENTED |
`define OR1200_DU_TBADR 11'h0ff |
`define OR1200_DU_TBIA 11'h1?? |
`define OR1200_DU_TBIM 11'h2?? |
`define OR1200_DU_TBAR 11'h3?? |
`define OR1200_DU_TBTS 11'h4?? |
`endif |
|
// Position of offset bits inside SPR address |
`define OR1200_DUOFS_BITS 10:0 |
|
// DCR bits |
`define OR1200_DU_DCR_DP 0 |
`define OR1200_DU_DCR_CC 3:1 |
`define OR1200_DU_DCR_SC 4 |
`define OR1200_DU_DCR_CT 7:5 |
|
// DMR1 bits |
`define OR1200_DU_DMR1_CW0 1:0 |
`define OR1200_DU_DMR1_CW1 3:2 |
`define OR1200_DU_DMR1_CW2 5:4 |
`define OR1200_DU_DMR1_CW3 7:6 |
`define OR1200_DU_DMR1_CW4 9:8 |
`define OR1200_DU_DMR1_CW5 11:10 |
`define OR1200_DU_DMR1_CW6 13:12 |
`define OR1200_DU_DMR1_CW7 15:14 |
`define OR1200_DU_DMR1_CW8 17:16 |
`define OR1200_DU_DMR1_CW9 19:18 |
`define OR1200_DU_DMR1_CW10 21:20 |
`define OR1200_DU_DMR1_ST 22 |
`define OR1200_DU_DMR1_BT 23 |
`define OR1200_DU_DMR1_DXFW 24 |
`define OR1200_DU_DMR1_ETE 25 |
|
// DMR2 bits |
`define OR1200_DU_DMR2_WCE0 0 |
`define OR1200_DU_DMR2_WCE1 1 |
`define OR1200_DU_DMR2_AWTC 12:2 |
`define OR1200_DU_DMR2_WGB 23:13 |
|
// DWCR bits |
`define OR1200_DU_DWCR_COUNT 15:0 |
`define OR1200_DU_DWCR_MATCH 31:16 |
|
// DSR bits |
`define OR1200_DU_DSR_WIDTH 14 |
`define OR1200_DU_DSR_RSTE 0 |
`define OR1200_DU_DSR_BUSEE 1 |
`define OR1200_DU_DSR_DPFE 2 |
`define OR1200_DU_DSR_IPFE 3 |
`define OR1200_DU_DSR_TTE 4 |
`define OR1200_DU_DSR_AE 5 |
`define OR1200_DU_DSR_IIE 6 |
`define OR1200_DU_DSR_IE 7 |
`define OR1200_DU_DSR_DME 8 |
`define OR1200_DU_DSR_IME 9 |
`define OR1200_DU_DSR_RE 10 |
`define OR1200_DU_DSR_SCE 11 |
`define OR1200_DU_DSR_FPE 12 |
`define OR1200_DU_DSR_TE 13 |
|
// DRR bits |
`define OR1200_DU_DRR_RSTE 0 |
`define OR1200_DU_DRR_BUSEE 1 |
`define OR1200_DU_DRR_DPFE 2 |
`define OR1200_DU_DRR_IPFE 3 |
`define OR1200_DU_DRR_TTE 4 |
`define OR1200_DU_DRR_AE 5 |
`define OR1200_DU_DRR_IIE 6 |
`define OR1200_DU_DRR_IE 7 |
`define OR1200_DU_DRR_DME 8 |
`define OR1200_DU_DRR_IME 9 |
`define OR1200_DU_DRR_RE 10 |
`define OR1200_DU_DRR_SCE 11 |
`define OR1200_DU_DRR_FPE 12 |
`define OR1200_DU_DRR_TE 13 |
|
// Define if reading DU regs is allowed |
`define OR1200_DU_READREGS |
|
// Define if unused DU registers bits should be zero |
`define OR1200_DU_UNUSED_ZERO |
|
// Define if IF/LSU status is not needed by devel i/f |
`define OR1200_DU_STATUS_UNIMPLEMENTED |
|
///////////////////////////////////////////////////// |
// |
// Programmable Interrupt Controller (PIC) |
// |
|
// Define it if you want PIC implemented |
`define OR1200_PIC_IMPLEMENTED |
|
// Define number of interrupt inputs (2-31) |
`define OR1200_PIC_INTS 31 |
|
// Address offsets of PIC registers inside PIC group |
`define OR1200_PIC_OFS_PICMR 2'd0 |
`define OR1200_PIC_OFS_PICSR 2'd2 |
|
// Position of offset bits inside SPR address |
`define OR1200_PICOFS_BITS 1:0 |
|
// Define if you want these PIC registers to be implemented |
`define OR1200_PIC_PICMR |
`define OR1200_PIC_PICSR |
|
// Define if reading PIC registers is allowed |
`define OR1200_PIC_READREGS |
|
// Define if unused PIC register bits should be zero |
`define OR1200_PIC_UNUSED_ZERO |
|
|
///////////////////////////////////////////////////// |
// |
// Tick Timer (TT) |
// |
|
// Define it if you want TT implemented |
`define OR1200_TT_IMPLEMENTED |
|
// Address offsets of TT registers inside TT group |
`define OR1200_TT_OFS_TTMR 1'd0 |
`define OR1200_TT_OFS_TTCR 1'd1 |
|
// Position of offset bits inside SPR group |
`define OR1200_TTOFS_BITS 0 |
|
// Define if you want these TT registers to be implemented |
`define OR1200_TT_TTMR |
`define OR1200_TT_TTCR |
|
// TTMR bits |
`define OR1200_TT_TTMR_TP 27:0 |
`define OR1200_TT_TTMR_IP 28 |
`define OR1200_TT_TTMR_IE 29 |
`define OR1200_TT_TTMR_M 31:30 |
|
// Define if reading TT registers is allowed |
`define OR1200_TT_READREGS |
|
|
////////////////////////////////////////////// |
// |
// MAC |
// |
`define OR1200_MAC_ADDR 0 // MACLO 0xxxxxxxx1, MACHI 0xxxxxxxx0 |
`define OR1200_MAC_SPR_WE // Define if MACLO/MACHI are SPR writable |
|
// |
// Shift {MACHI,MACLO} into destination register when executing l.macrc |
// |
// According to architecture manual there is no shift, so default value is 0. |
// However the implementation has deviated in this from the arch manual and had |
// hard coded shift by 28 bits which is a useful optimization for MP3 decoding |
// (if using libmad fixed point library). Shifts are no longer default setup, |
// but if you need to remain backward compatible, define your shift bits, which |
// were normally |
// dest_GPR = {MACHI,MACLO}[59:28] |
`define OR1200_MAC_SHIFTBY 0 // 0 = According to arch manual, 28 = obsolete backward compatibility |
|
|
////////////////////////////////////////////// |
// |
// Data MMU (DMMU) |
// |
|
// |
// Address that selects between TLB TR and MR |
// |
`define OR1200_DTLB_TM_ADDR 7 |
|
// |
// DTLBMR fields |
// |
`define OR1200_DTLBMR_V_BITS 0 |
`define OR1200_DTLBMR_CID_BITS 4:1 |
`define OR1200_DTLBMR_RES_BITS 11:5 |
`define OR1200_DTLBMR_VPN_BITS 31:13 |
|
// |
// DTLBTR fields |
// |
`define OR1200_DTLBTR_CC_BITS 0 |
`define OR1200_DTLBTR_CI_BITS 1 |
`define OR1200_DTLBTR_WBC_BITS 2 |
`define OR1200_DTLBTR_WOM_BITS 3 |
`define OR1200_DTLBTR_A_BITS 4 |
`define OR1200_DTLBTR_D_BITS 5 |
`define OR1200_DTLBTR_URE_BITS 6 |
`define OR1200_DTLBTR_UWE_BITS 7 |
`define OR1200_DTLBTR_SRE_BITS 8 |
`define OR1200_DTLBTR_SWE_BITS 9 |
`define OR1200_DTLBTR_RES_BITS 11:10 |
`define OR1200_DTLBTR_PPN_BITS 31:13 |
|
// |
// DTLB configuration |
// |
`define OR1200_DMMU_PS 13 // 13 for 8KB page size |
`define OR1200_DTLB_INDXW 6 // 6 for 64 entry DTLB 7 for 128 entries |
`define OR1200_DTLB_INDXL `OR1200_DMMU_PS // 13 13 |
`define OR1200_DTLB_INDXH `OR1200_DMMU_PS+`OR1200_DTLB_INDXW-1 // 18 19 |
`define OR1200_DTLB_INDX `OR1200_DTLB_INDXH:`OR1200_DTLB_INDXL // 18:13 19:13 |
`define OR1200_DTLB_TAGW 32-`OR1200_DTLB_INDXW-`OR1200_DMMU_PS // 13 12 |
`define OR1200_DTLB_TAGL `OR1200_DTLB_INDXH+1 // 19 20 |
`define OR1200_DTLB_TAG 31:`OR1200_DTLB_TAGL // 31:19 31:20 |
`define OR1200_DTLBMRW `OR1200_DTLB_TAGW+1 // +1 because of V bit |
`define OR1200_DTLBTRW 32-`OR1200_DMMU_PS+5 // +5 because of protection bits and CI |
|
// |
// Cache inhibit while DMMU is not enabled/implemented |
// |
// cache inhibited 0GB-4GB 1'b1 |
// cache inhibited 0GB-2GB !dcpu_adr_i[31] |
// cache inhibited 0GB-1GB 2GB-3GB !dcpu_adr_i[30] |
// cache inhibited 1GB-2GB 3GB-4GB dcpu_adr_i[30] |
// cache inhibited 2GB-4GB (default) dcpu_adr_i[31] |
// cached 0GB-4GB 1'b0 |
// |
`define OR1200_DMMU_CI dcpu_adr_i[31] |
|
|
////////////////////////////////////////////// |
// |
// Insn MMU (IMMU) |
// |
|
// |
// Address that selects between TLB TR and MR |
// |
`define OR1200_ITLB_TM_ADDR 7 |
|
// |
// ITLBMR fields |
// |
`define OR1200_ITLBMR_V_BITS 0 |
`define OR1200_ITLBMR_CID_BITS 4:1 |
`define OR1200_ITLBMR_RES_BITS 11:5 |
`define OR1200_ITLBMR_VPN_BITS 31:13 |
|
// |
// ITLBTR fields |
// |
`define OR1200_ITLBTR_CC_BITS 0 |
`define OR1200_ITLBTR_CI_BITS 1 |
`define OR1200_ITLBTR_WBC_BITS 2 |
`define OR1200_ITLBTR_WOM_BITS 3 |
`define OR1200_ITLBTR_A_BITS 4 |
`define OR1200_ITLBTR_D_BITS 5 |
`define OR1200_ITLBTR_SXE_BITS 6 |
`define OR1200_ITLBTR_UXE_BITS 7 |
`define OR1200_ITLBTR_RES_BITS 11:8 |
`define OR1200_ITLBTR_PPN_BITS 31:13 |
|
// |
// ITLB configuration |
// |
`define OR1200_IMMU_PS 13 // 13 for 8KB page size |
`define OR1200_ITLB_INDXW 6 // 6 for 64 entry ITLB 7 for 128 entries |
`define OR1200_ITLB_INDXL `OR1200_IMMU_PS // 13 13 |
`define OR1200_ITLB_INDXH `OR1200_IMMU_PS+`OR1200_ITLB_INDXW-1 // 18 19 |
`define OR1200_ITLB_INDX `OR1200_ITLB_INDXH:`OR1200_ITLB_INDXL // 18:13 19:13 |
`define OR1200_ITLB_TAGW 32-`OR1200_ITLB_INDXW-`OR1200_IMMU_PS // 13 12 |
`define OR1200_ITLB_TAGL `OR1200_ITLB_INDXH+1 // 19 20 |
`define OR1200_ITLB_TAG 31:`OR1200_ITLB_TAGL // 31:19 31:20 |
`define OR1200_ITLBMRW `OR1200_ITLB_TAGW+1 // +1 because of V bit |
`define OR1200_ITLBTRW 32-`OR1200_IMMU_PS+3 // +3 because of protection bits and CI |
|
// |
// Cache inhibit while IMMU is not enabled/implemented |
// Note: all combinations that use icpu_adr_i cause async loop |
// |
// cache inhibited 0GB-4GB 1'b1 |
// cache inhibited 0GB-2GB !icpu_adr_i[31] |
// cache inhibited 0GB-1GB 2GB-3GB !icpu_adr_i[30] |
// cache inhibited 1GB-2GB 3GB-4GB icpu_adr_i[30] |
// cache inhibited 2GB-4GB (default) icpu_adr_i[31] |
// cached 0GB-4GB 1'b0 |
// |
`define OR1200_IMMU_CI 1'b0 |
|
|
///////////////////////////////////////////////// |
// |
// Insn cache (IC) |
// |
|
// 4 for 16 byte line, 5 for 32 byte lines. |
`ifdef OR1200_IC_1W_32KB |
`define OR1200_ICLS 5 |
`else |
`define OR1200_ICLS 4 |
`endif |
|
// |
// IC configurations |
// |
`ifdef OR1200_IC_1W_512B |
`define OR1200_ICSIZE 9 // 512 |
`define OR1200_ICINDX `OR1200_ICSIZE-2 // 7 |
`define OR1200_ICINDXH `OR1200_ICSIZE-1 // 8 |
`define OR1200_ICTAGL `OR1200_ICINDXH+1 // 9 |
`define OR1200_ICTAG `OR1200_ICSIZE-`OR1200_ICLS // 5 |
`define OR1200_ICTAG_W 24 |
`endif |
`ifdef OR1200_IC_1W_4KB |
`define OR1200_ICSIZE 12 // 4096 |
`define OR1200_ICINDX `OR1200_ICSIZE-2 // 10 |
`define OR1200_ICINDXH `OR1200_ICSIZE-1 // 11 |
`define OR1200_ICTAGL `OR1200_ICINDXH+1 // 12 |
`define OR1200_ICTAG `OR1200_ICSIZE-`OR1200_ICLS // 8 |
`define OR1200_ICTAG_W 21 |
`endif |
`ifdef OR1200_IC_1W_8KB |
`define OR1200_ICSIZE 13 // 8192 |
`define OR1200_ICINDX `OR1200_ICSIZE-2 // 11 |
`define OR1200_ICINDXH `OR1200_ICSIZE-1 // 12 |
`define OR1200_ICTAGL `OR1200_ICINDXH+1 // 13 |
`define OR1200_ICTAG `OR1200_ICSIZE-`OR1200_ICLS // 9 |
`define OR1200_ICTAG_W 20 |
`endif |
`ifdef OR1200_IC_1W_16KB |
`define OR1200_ICSIZE 14 // 16384 |
`define OR1200_ICINDX `OR1200_ICSIZE-2 // 12 |
`define OR1200_ICINDXH `OR1200_ICSIZE-1 // 13 |
`define OR1200_ICTAGL `OR1200_ICINDXH+1 // 14 |
`define OR1200_ICTAG `OR1200_ICSIZE-`OR1200_ICLS // 10 |
`define OR1200_ICTAG_W 19 |
`endif |
`ifdef OR1200_IC_1W_32KB |
`define OR1200_ICSIZE 15 // 32768 |
`define OR1200_ICINDX `OR1200_ICSIZE-2 // 13 |
`define OR1200_ICINDXH `OR1200_ICSIZE-1 // 14 |
`define OR1200_ICTAGL `OR1200_ICINDXH+1 // 14 |
`define OR1200_ICTAG `OR1200_ICSIZE-`OR1200_ICLS // 10 |
`define OR1200_ICTAG_W 18 |
`endif |
|
|
///////////////////////////////////////////////// |
// |
// Data cache (DC) |
// |
|
// 4 for 16 bytes, 5 for 32 bytes |
`ifdef OR1200_DC_1W_32KB |
`define OR1200_DCLS 5 |
`else |
`define OR1200_DCLS 4 |
`endif |
|
// Define to enable default behavior of cache as write through |
// Turning this off enabled write back statergy |
// |
`define OR1200_DC_WRITETHROUGH |
|
// Define to enable stores from the stack not doing writethrough. |
// EXPERIMENTAL |
//`define OR1200_DC_NOSTACKWRITETHROUGH |
|
// Data cache SPR definitions |
`define OR1200_SPRGRP_DC_ADR_WIDTH 3 |
// Data cache group SPR addresses |
`define OR1200_SPRGRP_DC_DCCR 3'd0 // Not implemented |
`define OR1200_SPRGRP_DC_DCBPR 3'd1 // Not implemented |
`define OR1200_SPRGRP_DC_DCBFR 3'd2 |
`define OR1200_SPRGRP_DC_DCBIR 3'd3 |
`define OR1200_SPRGRP_DC_DCBWR 3'd4 // Not implemented |
`define OR1200_SPRGRP_DC_DCBLR 3'd5 // Not implemented |
|
// |
// DC configurations |
// |
`ifdef OR1200_DC_1W_4KB |
`define OR1200_DCSIZE 12 // 4096 |
`define OR1200_DCINDX `OR1200_DCSIZE-2 // 10 |
`define OR1200_DCINDXH `OR1200_DCSIZE-1 // 11 |
`define OR1200_DCTAGL `OR1200_DCINDXH+1 // 12 |
`define OR1200_DCTAG `OR1200_DCSIZE-`OR1200_DCLS // 8 |
`define OR1200_DCTAG_W 21 |
`endif |
`ifdef OR1200_DC_1W_8KB |
`define OR1200_DCSIZE 13 // 8192 |
`define OR1200_DCINDX `OR1200_DCSIZE-2 // 11 |
`define OR1200_DCINDXH `OR1200_DCSIZE-1 // 12 |
`define OR1200_DCTAGL `OR1200_DCINDXH+1 // 13 |
`define OR1200_DCTAG `OR1200_DCSIZE-`OR1200_DCLS // 9 |
`define OR1200_DCTAG_W 20 |
`endif |
`ifdef OR1200_DC_1W_16KB |
`define OR1200_DCSIZE 14 // 16384 |
`define OR1200_DCINDX `OR1200_DCSIZE-2 // 12 |
`define OR1200_DCINDXH `OR1200_DCSIZE-1 // 13 |
`define OR1200_DCTAGL `OR1200_DCINDXH+1 // 14 |
`define OR1200_DCTAG `OR1200_DCSIZE-`OR1200_DCLS // 10 |
`define OR1200_DCTAG_W 19 |
`endif |
`ifdef OR1200_DC_1W_32KB |
`define OR1200_DCSIZE 15 // 32768 |
`define OR1200_DCINDX `OR1200_DCSIZE-2 // 13 |
`define OR1200_DCINDXH `OR1200_DCSIZE-1 // 14 |
`define OR1200_DCTAGL `OR1200_DCINDXH+1 // 15 |
`define OR1200_DCTAG `OR1200_DCSIZE-`OR1200_DCLS // 10 |
`define OR1200_DCTAG_W 18 |
`endif |
|
|
///////////////////////////////////////////////// |
// |
// Store buffer (SB) |
// |
|
// |
// Store buffer |
// |
// It will improve performance by "caching" CPU stores |
// using store buffer. This is most important for function |
// prologues because DC can only work in write though mode |
// and all stores would have to complete external WB writes |
// to memory. |
// Store buffer is between DC and data BIU. |
// All stores will be stored into store buffer and immediately |
// completed by the CPU, even though actual external writes |
// will be performed later. As a consequence store buffer masks |
// all data bus errors related to stores (data bus errors |
// related to loads are delivered normally). |
// All pending CPU loads will wait until store buffer is empty to |
// ensure strict memory model. Right now this is necessary because |
// we don't make destinction between cached and cache inhibited |
// address space, so we simply empty store buffer until loads |
// can begin. |
// |
// It makes design a bit bigger, depending what is the number of |
// entries in SB FIFO. Number of entries can be changed further |
// down. |
// |
//`define OR1200_SB_IMPLEMENTED |
|
// |
// Number of store buffer entries |
// |
// Verified number of entries are 4 and 8 entries |
// (2 and 3 for OR1200_SB_LOG). OR1200_SB_ENTRIES must |
// always match 2**OR1200_SB_LOG. |
// To disable store buffer, undefine |
// OR1200_SB_IMPLEMENTED. |
// |
`define OR1200_SB_LOG 2 // 2 or 3 |
`define OR1200_SB_ENTRIES 4 // 4 or 8 |
|
|
///////////////////////////////////////////////// |
// |
// Quick Embedded Memory (QMEM) |
// |
|
// |
// Quick Embedded Memory |
// |
// Instantiation of dedicated insn/data memory (RAM or ROM). |
// Insn fetch has effective throughput 1insn / clock cycle. |
// Data load takes two clock cycles / access, data store |
// takes 1 clock cycle / access (if there is no insn fetch)). |
// Memory instantiation is shared between insn and data, |
// meaning if insn fetch are performed, data load/store |
// performance will be lower. |
// |
// Main reason for QMEM is to put some time critical functions |
// into this memory and to have predictable and fast access |
// to these functions. (soft fpu, context switch, exception |
// handlers, stack, etc) |
// |
// It makes design a bit bigger and slower. QMEM sits behind |
// IMMU/DMMU so all addresses are physical (so the MMUs can be |
// used with QMEM and QMEM is seen by the CPU just like any other |
// memory in the system). IC/DC are sitting behind QMEM so the |
// whole design timing might be worse with QMEM implemented. |
// |
//`define OR1200_QMEM_IMPLEMENTED |
|
// |
// Base address and mask of QMEM |
// |
// Base address defines first address of QMEM. Mask defines |
// QMEM range in address space. Actual size of QMEM is however |
// determined with instantiated RAM/ROM. However bigger |
// mask will reserve more address space for QMEM, but also |
// make design faster, while more tight mask will take |
// less address space but also make design slower. If |
// instantiated RAM/ROM is smaller than space reserved with |
// the mask, instatiated RAM/ROM will also be shadowed |
// at higher addresses in reserved space. |
// |
`define OR1200_QMEM_IADDR 32'h0080_0000 |
`define OR1200_QMEM_IMASK 32'hfff0_0000 // Max QMEM size 1MB |
`define OR1200_QMEM_DADDR 32'h0080_0000 |
`define OR1200_QMEM_DMASK 32'hfff0_0000 // Max QMEM size 1MB |
|
// |
// QMEM interface byte-select capability |
// |
// To enable qmem_sel* ports, define this macro. |
// |
//`define OR1200_QMEM_BSEL |
|
// |
// QMEM interface acknowledge |
// |
// To enable qmem_ack port, define this macro. |
// |
//`define OR1200_QMEM_ACK |
|
///////////////////////////////////////////////////// |
// |
// VR, UPR and Configuration Registers |
// |
// |
// VR, UPR and configuration registers are optional. If |
// implemented, operating system can automatically figure |
// out how to use the processor because it knows |
// what units are available in the processor and how they |
// are configured. |
// |
// This section must be last in or1200_defines.v file so |
// that all units are already configured and thus |
// configuration registers are properly set. |
// |
|
// Define if you want configuration registers implemented |
`define OR1200_CFGR_IMPLEMENTED |
|
// Define if you want full address decode inside SYS group |
`define OR1200_SYS_FULL_DECODE |
|
// Offsets of VR, UPR and CFGR registers |
`define OR1200_SPRGRP_SYS_VR 4'h0 |
`define OR1200_SPRGRP_SYS_UPR 4'h1 |
`define OR1200_SPRGRP_SYS_CPUCFGR 4'h2 |
`define OR1200_SPRGRP_SYS_DMMUCFGR 4'h3 |
`define OR1200_SPRGRP_SYS_IMMUCFGR 4'h4 |
`define OR1200_SPRGRP_SYS_DCCFGR 4'h5 |
`define OR1200_SPRGRP_SYS_ICCFGR 4'h6 |
`define OR1200_SPRGRP_SYS_DCFGR 4'h7 |
|
// VR fields |
`define OR1200_VR_REV_BITS 5:0 |
`define OR1200_VR_RES1_BITS 15:6 |
`define OR1200_VR_CFG_BITS 23:16 |
`define OR1200_VR_VER_BITS 31:24 |
|
// VR values |
`define OR1200_VR_REV 6'h08 |
`define OR1200_VR_RES1 10'h000 |
`define OR1200_VR_CFG 8'h00 |
`define OR1200_VR_VER 8'h12 |
|
// UPR fields |
`define OR1200_UPR_UP_BITS 0 |
`define OR1200_UPR_DCP_BITS 1 |
`define OR1200_UPR_ICP_BITS 2 |
`define OR1200_UPR_DMP_BITS 3 |
`define OR1200_UPR_IMP_BITS 4 |
`define OR1200_UPR_MP_BITS 5 |
`define OR1200_UPR_DUP_BITS 6 |
`define OR1200_UPR_PCUP_BITS 7 |
`define OR1200_UPR_PMP_BITS 8 |
`define OR1200_UPR_PICP_BITS 9 |
`define OR1200_UPR_TTP_BITS 10 |
`define OR1200_UPR_FPP_BITS 11 |
`define OR1200_UPR_RES1_BITS 23:12 |
`define OR1200_UPR_CUP_BITS 31:24 |
|
// UPR values |
`define OR1200_UPR_UP 1'b1 |
`ifdef OR1200_NO_DC |
`define OR1200_UPR_DCP 1'b0 |
`else |
`define OR1200_UPR_DCP 1'b1 |
`endif |
`ifdef OR1200_NO_IC |
`define OR1200_UPR_ICP 1'b0 |
`else |
`define OR1200_UPR_ICP 1'b1 |
`endif |
`ifdef OR1200_NO_DMMU |
`define OR1200_UPR_DMP 1'b0 |
`else |
`define OR1200_UPR_DMP 1'b1 |
`endif |
`ifdef OR1200_NO_IMMU |
`define OR1200_UPR_IMP 1'b0 |
`else |
`define OR1200_UPR_IMP 1'b1 |
`endif |
`ifdef OR1200_MAC_IMPLEMENTED |
`define OR1200_UPR_MP 1'b1 |
`else |
`define OR1200_UPR_MP 1'b0 |
`endif |
`ifdef OR1200_DU_IMPLEMENTED |
`define OR1200_UPR_DUP 1'b1 |
`else |
`define OR1200_UPR_DUP 1'b0 |
`endif |
`define OR1200_UPR_PCUP 1'b0 // Performance counters not present |
`ifdef OR1200_PM_IMPLEMENTED |
`define OR1200_UPR_PMP 1'b1 |
`else |
`define OR1200_UPR_PMP 1'b0 |
`endif |
`ifdef OR1200_PIC_IMPLEMENTED |
`define OR1200_UPR_PICP 1'b1 |
`else |
`define OR1200_UPR_PICP 1'b0 |
`endif |
`ifdef OR1200_TT_IMPLEMENTED |
`define OR1200_UPR_TTP 1'b1 |
`else |
`define OR1200_UPR_TTP 1'b0 |
`endif |
`ifdef OR1200_FPU_IMPLEMENTED |
`define OR1200_UPR_FPP 1'b1 |
`else |
`define OR1200_UPR_FPP 1'b0 |
`endif |
`define OR1200_UPR_RES1 12'h000 |
`define OR1200_UPR_CUP 8'h00 |
|
// CPUCFGR fields |
`define OR1200_CPUCFGR_NSGF_BITS 3:0 |
`define OR1200_CPUCFGR_HGF_BITS 4 |
`define OR1200_CPUCFGR_OB32S_BITS 5 |
`define OR1200_CPUCFGR_OB64S_BITS 6 |
`define OR1200_CPUCFGR_OF32S_BITS 7 |
`define OR1200_CPUCFGR_OF64S_BITS 8 |
`define OR1200_CPUCFGR_OV64S_BITS 9 |
`define OR1200_CPUCFGR_RES1_BITS 31:10 |
|
// CPUCFGR values |
`define OR1200_CPUCFGR_NSGF 4'h0 |
`ifdef OR1200_RFRAM_16REG |
`define OR1200_CPUCFGR_HGF 1'b1 |
`else |
`define OR1200_CPUCFGR_HGF 1'b0 |
`endif |
`define OR1200_CPUCFGR_OB32S 1'b1 |
`define OR1200_CPUCFGR_OB64S 1'b0 |
`ifdef OR1200_FPU_IMPLEMENTED |
`define OR1200_CPUCFGR_OF32S 1'b1 |
`else |
`define OR1200_CPUCFGR_OF32S 1'b0 |
`endif |
|
`define OR1200_CPUCFGR_OF64S 1'b0 |
`define OR1200_CPUCFGR_OV64S 1'b0 |
`define OR1200_CPUCFGR_RES1 22'h000000 |
|
// DMMUCFGR fields |
`define OR1200_DMMUCFGR_NTW_BITS 1:0 |
`define OR1200_DMMUCFGR_NTS_BITS 4:2 |
`define OR1200_DMMUCFGR_NAE_BITS 7:5 |
`define OR1200_DMMUCFGR_CRI_BITS 8 |
`define OR1200_DMMUCFGR_PRI_BITS 9 |
`define OR1200_DMMUCFGR_TEIRI_BITS 10 |
`define OR1200_DMMUCFGR_HTR_BITS 11 |
`define OR1200_DMMUCFGR_RES1_BITS 31:12 |
|
// DMMUCFGR values |
`ifdef OR1200_NO_DMMU |
`define OR1200_DMMUCFGR_NTW 2'h0 // Irrelevant |
`define OR1200_DMMUCFGR_NTS 3'h0 // Irrelevant |
`define OR1200_DMMUCFGR_NAE 3'h0 // Irrelevant |
`define OR1200_DMMUCFGR_CRI 1'b0 // Irrelevant |
`define OR1200_DMMUCFGR_PRI 1'b0 // Irrelevant |
`define OR1200_DMMUCFGR_TEIRI 1'b0 // Irrelevant |
`define OR1200_DMMUCFGR_HTR 1'b0 // Irrelevant |
`define OR1200_DMMUCFGR_RES1 20'h00000 |
`else |
`define OR1200_DMMUCFGR_NTW 2'h0 // 1 TLB way |
`define OR1200_DMMUCFGR_NTS 3'h`OR1200_DTLB_INDXW // Num TLB sets |
`define OR1200_DMMUCFGR_NAE 3'h0 // No ATB entries |
`define OR1200_DMMUCFGR_CRI 1'b0 // No control register |
`define OR1200_DMMUCFGR_PRI 1'b0 // No protection reg |
`define OR1200_DMMUCFGR_TEIRI 1'b0 // TLB entry inv reg NOT impl. |
`define OR1200_DMMUCFGR_HTR 1'b0 // No HW TLB reload |
`define OR1200_DMMUCFGR_RES1 20'h00000 |
`endif |
|
// IMMUCFGR fields |
`define OR1200_IMMUCFGR_NTW_BITS 1:0 |
`define OR1200_IMMUCFGR_NTS_BITS 4:2 |
`define OR1200_IMMUCFGR_NAE_BITS 7:5 |
`define OR1200_IMMUCFGR_CRI_BITS 8 |
`define OR1200_IMMUCFGR_PRI_BITS 9 |
`define OR1200_IMMUCFGR_TEIRI_BITS 10 |
`define OR1200_IMMUCFGR_HTR_BITS 11 |
`define OR1200_IMMUCFGR_RES1_BITS 31:12 |
|
// IMMUCFGR values |
`ifdef OR1200_NO_IMMU |
`define OR1200_IMMUCFGR_NTW 2'h0 // Irrelevant |
`define OR1200_IMMUCFGR_NTS 3'h0 // Irrelevant |
`define OR1200_IMMUCFGR_NAE 3'h0 // Irrelevant |
`define OR1200_IMMUCFGR_CRI 1'b0 // Irrelevant |
`define OR1200_IMMUCFGR_PRI 1'b0 // Irrelevant |
`define OR1200_IMMUCFGR_TEIRI 1'b0 // Irrelevant |
`define OR1200_IMMUCFGR_HTR 1'b0 // Irrelevant |
`define OR1200_IMMUCFGR_RES1 20'h00000 |
`else |
`define OR1200_IMMUCFGR_NTW 2'h0 // 1 TLB way |
`define OR1200_IMMUCFGR_NTS 3'h`OR1200_ITLB_INDXW // Num TLB sets |
`define OR1200_IMMUCFGR_NAE 3'h0 // No ATB entry |
`define OR1200_IMMUCFGR_CRI 1'b0 // No control reg |
`define OR1200_IMMUCFGR_PRI 1'b0 // No protection reg |
`define OR1200_IMMUCFGR_TEIRI 1'b0 // TLB entry inv reg NOT impl |
`define OR1200_IMMUCFGR_HTR 1'b0 // No HW TLB reload |
`define OR1200_IMMUCFGR_RES1 20'h00000 |
`endif |
|
// DCCFGR fields |
`define OR1200_DCCFGR_NCW_BITS 2:0 |
`define OR1200_DCCFGR_NCS_BITS 6:3 |
`define OR1200_DCCFGR_CBS_BITS 7 |
`define OR1200_DCCFGR_CWS_BITS 8 |
`define OR1200_DCCFGR_CCRI_BITS 9 |
`define OR1200_DCCFGR_CBIRI_BITS 10 |
`define OR1200_DCCFGR_CBPRI_BITS 11 |
`define OR1200_DCCFGR_CBLRI_BITS 12 |
`define OR1200_DCCFGR_CBFRI_BITS 13 |
`define OR1200_DCCFGR_CBWBRI_BITS 14 |
`define OR1200_DCCFGR_RES1_BITS 31:15 |
|
// DCCFGR values |
`ifdef OR1200_NO_DC |
`define OR1200_DCCFGR_NCW 3'h0 // Irrelevant |
`define OR1200_DCCFGR_NCS 4'h0 // Irrelevant |
`define OR1200_DCCFGR_CBS 1'b0 // Irrelevant |
`define OR1200_DCCFGR_CWS 1'b0 // Irrelevant |
`define OR1200_DCCFGR_CCRI 1'b0 // Irrelevant |
`define OR1200_DCCFGR_CBIRI 1'b0 // Irrelevant |
`define OR1200_DCCFGR_CBPRI 1'b0 // Irrelevant |
`define OR1200_DCCFGR_CBLRI 1'b0 // Irrelevant |
`define OR1200_DCCFGR_CBFRI 1'b0 // Irrelevant |
`define OR1200_DCCFGR_CBWBRI 1'b0 // Irrelevant |
`define OR1200_DCCFGR_RES1 17'h00000 |
`else |
`define OR1200_DCCFGR_NCW 3'h0 // 1 cache way |
`define OR1200_DCCFGR_NCS (`OR1200_DCTAG) // Num cache sets |
`define OR1200_DCCFGR_CBS `OR1200_DCLS==4 ? 1'b0 : 1'b1 // 16 byte cache block |
`ifdef OR1200_DC_WRITETHROUGH |
`define OR1200_DCCFGR_CWS 1'b0 // Write-through strategy |
`else |
`define OR1200_DCCFGR_CWS 1'b1 // Write-back strategy |
`endif |
`define OR1200_DCCFGR_CCRI 1'b1 // Cache control reg impl. |
`define OR1200_DCCFGR_CBIRI 1'b1 // Cache block inv reg impl. |
`define OR1200_DCCFGR_CBPRI 1'b0 // Cache block prefetch reg not impl. |
`define OR1200_DCCFGR_CBLRI 1'b0 // Cache block lock reg not impl. |
`define OR1200_DCCFGR_CBFRI 1'b1 // Cache block flush reg impl. |
`ifdef OR1200_DC_WRITETHROUGH |
`define OR1200_DCCFGR_CBWBRI 1'b0 // Cache block WB reg not impl. |
`else |
`define OR1200_DCCFGR_CBWBRI 1'b1 // Cache block WB reg impl. |
`endif |
`define OR1200_DCCFGR_RES1 17'h00000 |
`endif |
|
// ICCFGR fields |
`define OR1200_ICCFGR_NCW_BITS 2:0 |
`define OR1200_ICCFGR_NCS_BITS 6:3 |
`define OR1200_ICCFGR_CBS_BITS 7 |
`define OR1200_ICCFGR_CWS_BITS 8 |
`define OR1200_ICCFGR_CCRI_BITS 9 |
`define OR1200_ICCFGR_CBIRI_BITS 10 |
`define OR1200_ICCFGR_CBPRI_BITS 11 |
`define OR1200_ICCFGR_CBLRI_BITS 12 |
`define OR1200_ICCFGR_CBFRI_BITS 13 |
`define OR1200_ICCFGR_CBWBRI_BITS 14 |
`define OR1200_ICCFGR_RES1_BITS 31:15 |
|
// ICCFGR values |
`ifdef OR1200_NO_IC |
`define OR1200_ICCFGR_NCW 3'h0 // Irrelevant |
`define OR1200_ICCFGR_NCS 4'h0 // Irrelevant |
`define OR1200_ICCFGR_CBS 1'b0 // Irrelevant |
`define OR1200_ICCFGR_CWS 1'b0 // Irrelevant |
`define OR1200_ICCFGR_CCRI 1'b0 // Irrelevant |
`define OR1200_ICCFGR_CBIRI 1'b0 // Irrelevant |
`define OR1200_ICCFGR_CBPRI 1'b0 // Irrelevant |
`define OR1200_ICCFGR_CBLRI 1'b0 // Irrelevant |
`define OR1200_ICCFGR_CBFRI 1'b0 // Irrelevant |
`define OR1200_ICCFGR_CBWBRI 1'b0 // Irrelevant |
`define OR1200_ICCFGR_RES1 17'h00000 |
`else |
`define OR1200_ICCFGR_NCW 3'h0 // 1 cache way |
`define OR1200_ICCFGR_NCS (`OR1200_ICTAG) // Num cache sets |
`define OR1200_ICCFGR_CBS `OR1200_ICLS==4 ? 1'b0: 1'b1 // 16 byte cache block |
`define OR1200_ICCFGR_CWS 1'b0 // Irrelevant |
`define OR1200_ICCFGR_CCRI 1'b1 // Cache control reg impl. |
`define OR1200_ICCFGR_CBIRI 1'b1 // Cache block inv reg impl. |
`define OR1200_ICCFGR_CBPRI 1'b0 // Cache block prefetch reg not impl. |
`define OR1200_ICCFGR_CBLRI 1'b0 // Cache block lock reg not impl. |
`define OR1200_ICCFGR_CBFRI 1'b1 // Cache block flush reg impl. |
`define OR1200_ICCFGR_CBWBRI 1'b0 // Irrelevant |
`define OR1200_ICCFGR_RES1 17'h00000 |
`endif |
|
// DCFGR fields |
`define OR1200_DCFGR_NDP_BITS 3:0 |
`define OR1200_DCFGR_WPCI_BITS 4 |
`define OR1200_DCFGR_RES1_BITS 31:5 |
|
// DCFGR values |
`ifdef OR1200_DU_HWBKPTS |
`define OR1200_DCFGR_NDP 4'h`OR1200_DU_DVRDCR_PAIRS // # of DVR/DCR pairs |
`ifdef OR1200_DU_DWCR0 |
`define OR1200_DCFGR_WPCI 1'b1 |
`else |
`define OR1200_DCFGR_WPCI 1'b0 // WP counters not impl. |
`endif |
`else |
`define OR1200_DCFGR_NDP 4'h0 // Zero DVR/DCR pairs |
`define OR1200_DCFGR_WPCI 1'b0 // WP counters not impl. |
`endif |
`define OR1200_DCFGR_RES1 27'd0 |
|
/////////////////////////////////////////////////////////////////////////////// |
// Boot Address Selection // |
// // |
// Allows a definable boot address, potentially different to the usual reset // |
// vector to allow for power-on code to be run, if desired. // |
// // |
// OR1200_BOOT_ADR should be the 32-bit address of the boot location // |
// OR1200_BOOT_PCREG_DEFAULT should be ((OR1200_BOOT_ADR-4)>>2) // |
// // |
// For default reset behavior uncomment the settings under the "Boot 0x100" // |
// comment below. // |
// // |
/////////////////////////////////////////////////////////////////////////////// |
// Boot from 0xf0000100 |
`define OR1200_BOOT_PCREG_DEFAULT 30'h3c00003f |
`define OR1200_BOOT_ADR 32'hf0000100 |
// Boot from 0x100 |
//`define OR1200_BOOT_PCREG_DEFAULT 30'h0000003f |
//`define OR1200_BOOT_ADR 32'h00000100 |
/s3adsp1800/rtl/verilog/include/dbg_wb_defines.v
0,0 → 1,113
////////////////////////////////////////////////////////////////////// |
//// //// |
//// dbg_wb_defines.v //// |
//// //// |
//// //// |
//// This file is part of the SoC Debug Interface. //// |
//// http://www.opencores.org/projects/DebugInterface/ //// |
//// //// |
//// Author(s): //// |
//// Igor Mohor (igorm@opencores.org) //// |
//// //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 - 2004 Authors //// |
//// //// |
//// 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: dbg_wb_defines.v,v $ |
// Revision 1.7 2004/03/31 14:34:08 igorm |
// data_cnt_lim length changed to reduce number of warnings. |
// |
// Revision 1.6 2004/03/28 20:27:02 igorm |
// New release of the debug interface (3rd. release). |
// |
// Revision 1.5 2004/03/22 16:35:46 igorm |
// Temp version before changing dbg interface. |
// |
// Revision 1.4 2004/01/16 14:51:33 mohor |
// cpu registers added. |
// |
// Revision 1.3 2004/01/08 17:53:36 mohor |
// tmp version. |
// |
// Revision 1.2 2004/01/06 17:15:19 mohor |
// temp3 version. |
// |
// Revision 1.1 2003/12/23 15:09:04 mohor |
// New directory structure. New version of the debug interface. |
// |
// |
// |
|
// Defining length of the command |
`define DBG_WB_CMD_LEN 3'd4 |
`define DBG_WB_CMD_LEN_INT 4 |
`define DBG_WB_CMD_CNT_WIDTH 3 |
|
// Defining length of the access_type field |
`define DBG_WB_ACC_TYPE_LEN 4 |
|
|
// Defining length of the address |
`define DBG_WB_ADR_LEN 32 |
|
// Defining length of the length register |
`define DBG_WB_LEN_LEN 16 |
|
// Defining total length of the DR needed |
`define DBG_WB_DR_LEN (`DBG_WB_ACC_TYPE_LEN + `DBG_WB_ADR_LEN + `DBG_WB_LEN_LEN) |
|
// Defining length of the CRC |
`define DBG_WB_CRC_LEN 6'd32 |
`define DBG_WB_CRC_CNT_WIDTH 6 |
|
// Defining length of status |
`define DBG_WB_STATUS_LEN 3'd4 |
`define DBG_WB_STATUS_CNT_WIDTH 3 |
|
// Defining length of the data |
`define DBG_WB_DATA_CNT_WIDTH (`DBG_WB_LEN_LEN + 3) |
`define DBG_WB_DATA_CNT_LIM_WIDTH `DBG_WB_LEN_LEN |
|
//Defining commands |
`define DBG_WB_GO 4'h0 |
`define DBG_WB_RD_COMM 4'h1 |
`define DBG_WB_WR_COMM 4'h2 |
|
// Defining access types for wishbone |
`define DBG_WB_WRITE8 4'h0 |
`define DBG_WB_WRITE16 4'h1 |
`define DBG_WB_WRITE32 4'h2 |
`define DBG_WB_READ8 4'h4 |
`define DBG_WB_READ16 4'h5 |
`define DBG_WB_READ32 4'h6 |
|
|
/s3adsp1800/rtl/verilog/include/tap_defines.v
0,0 → 1,69
////////////////////////////////////////////////////////////////////// |
//// //// |
//// tap_defines.v //// |
//// //// |
//// //// |
//// This file is part of the JTAG Test Access Port (TAP) //// |
//// http://www.opencores.org/projects/jtag/ //// |
//// //// |
//// Author(s): //// |
//// Igor Mohor (igorm@opencores.org) //// |
//// //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 - 2003 Authors //// |
//// //// |
//// 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: tap_defines.v,v $ |
// Revision 1.2 2004/01/27 10:00:33 mohor |
// Unused registers removed. |
// |
// Revision 1.1 2003/12/23 14:52:14 mohor |
// Directory structure changed. New version of TAP. |
// |
// |
// |
|
|
// Define IDCODE Value |
`define IDCODE_VALUE 32'h14951185 |
|
// Length of the Instruction register |
`define IR_LENGTH 4 |
|
// Supported Instructions |
`define EXTEST 4'b0000 |
`define SAMPLE_PRELOAD 4'b0001 |
`define IDCODE 4'b0010 |
`define DEBUG 4'b1000 |
`define MBIST 4'b1001 |
`define BYPASS 4'b1111 |
|
/s3adsp1800/rtl/verilog/include/orpsoc-params.v
0,0 → 1,165
////////////////////////////////////////////////////////////////////// |
//// //// |
//// orpsoc-params //// |
//// //// |
//// Top level ORPSoC parameters file //// |
//// //// |
//// Included in toplevel and testbench //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009, 2010 Authors and 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
/////////////////////////// |
// // |
// Peripheral parameters // |
// // |
/////////////////////////// |
|
// SPI 0 params |
parameter spi0_ss_width = 1; |
parameter spi0_wb_adr = 8'hb0; |
parameter wbs_d_spi0_data_width = 8; |
parameter spi0_wb_adr_width = 3; |
|
// i2c master slave params |
// Slave addresses |
parameter HV0_SADR = 8'h44; |
parameter HV1_SADR = 8'h45; |
parameter HV2_SADR = 8'h46; |
parameter HV3_SADR = 8'h47; |
|
// i2c 0 params |
parameter i2c_0_wb_adr = 8'ha0; |
parameter i2c_0_wb_adr_width = 3; |
parameter wbs_d_i2c0_data_width = 8; |
|
// i2c 1 params |
parameter i2c_1_wb_adr = 8'ha1; |
parameter i2c_1_wb_adr_width = 3; |
parameter wbs_d_i2c1_data_width = 8; |
|
|
// GPIO 0 params |
parameter wbs_d_gpio0_data_width = 8; |
parameter gpio0_wb_adr_width = 3; |
parameter gpio0_io_width = 24; |
parameter gpio0_wb_adr = 8'h91; |
parameter gpio0_dir_reset_val = 0; |
parameter gpio0_o_reset_val = 0; |
|
// UART 0 params |
parameter wbs_d_uart0_data_width = 8; |
parameter uart0_wb_adr = 8'h90; |
parameter uart0_data_width = 8; |
parameter uart0_addr_width = 3; |
|
// ROM |
parameter wbs_i_rom0_data_width = 32; |
parameter wbs_i_rom0_addr_width = 6; |
parameter rom0_wb_adr = 4'hf; |
|
// MC0 (SDRAM, or other) |
parameter wbs_i_mc0_data_width = 32; |
parameter wbs_d_mc0_data_width = 32; |
|
// ETH0 defines |
parameter eth0_wb_adr = 8'h92; |
parameter wbs_d_eth0_data_width = 32; |
parameter wbs_d_eth0_addr_width = 12; |
parameter wbm_eth0_data_width = 32; |
parameter wbm_eth0_addr_width = 32; |
|
// Memory sizing for synthesis (small) |
parameter internal_sram_mem_span = 32'h0080_0000; |
parameter internal_sram_adr_width_for_span = 23; |
|
////////////////////////////////////////////////////// |
// // |
// Wishbone bus parameters // |
// // |
////////////////////////////////////////////////////// |
|
//////////////////////// |
// // |
// Arbiter parameters // |
// // |
//////////////////////// |
|
parameter wb_dw = 32; // Default Wishbone full word width |
parameter wb_aw = 32; // Default Wishbone full address width |
|
/////////////////////////// |
// // |
// Instruction bus // |
// // |
/////////////////////////// |
parameter ibus_arb_addr_match_width = 4; |
// Slave addresses |
parameter ibus_arb_slave0_adr = rom0_wb_adr; // FLASH ROM |
parameter ibus_arb_slave1_adr = 4'h0; // Main memory (SDRAM/FPGA SRAM) |
|
/////////////////////////// |
// // |
// Data bus // |
// // |
/////////////////////////// |
// Has auto foward to last slave when no address hits |
parameter dbus_arb_wb_addr_match_width = 8; |
parameter dbus_arb_wb_num_slaves = 5; |
// Slave addresses |
parameter dbus_arb_slave0_adr = 4'h0; // Main memory (SDRAM/FPGA SRAM) |
parameter dbus_arb_slave1_adr = eth0_wb_adr; // Ethernet 0 |
|
/////////////////////////////// |
// // |
// Byte-wide peripheral bus // |
// // |
/////////////////////////////// |
parameter bbus_arb_wb_addr_match_width = 8; |
parameter bbus_arb_wb_num_slaves = 5; // Update this when changing slaves! |
// Slave addresses |
parameter bbus_arb_slave0_adr = uart0_wb_adr; |
parameter bbus_arb_slave1_adr = gpio0_wb_adr; |
parameter bbus_arb_slave2_adr = i2c_0_wb_adr; |
parameter bbus_arb_slave3_adr = i2c_1_wb_adr; |
parameter bbus_arb_slave4_adr = spi0_wb_adr; |
parameter bbus_arb_slave5_adr = 0 /* UNASSIGNED */; |
parameter bbus_arb_slave6_adr = 0 /* UNASSIGNED */; |
parameter bbus_arb_slave7_adr = 0 /* UNASSIGNED */; |
parameter bbus_arb_slave8_adr = 0 /* UNASSIGNED */; |
parameter bbus_arb_slave9_adr = 0 /* UNASSIGNED */; |
parameter bbus_arb_slave10_adr = 0 /* UNASSIGNED */; |
parameter bbus_arb_slave11_adr = 0 /* UNASSIGNED */; |
parameter bbus_arb_slave12_adr = 0 /* UNASSIGNED */; |
parameter bbus_arb_slave13_adr = 0 /* UNASSIGNED */; |
parameter bbus_arb_slave14_adr = 0 /* UNASSIGNED */; |
parameter bbus_arb_slave15_adr = 0 /* UNASSIGNED */; |
parameter bbus_arb_slave16_adr = 0 /* UNASSIGNED */; |
|
|
|
|
/s3adsp1800/rtl/verilog/include/uart_defines.v
0,0 → 1,254
////////////////////////////////////////////////////////////////////// |
//// //// |
//// uart_defines.v //// |
//// //// |
//// //// |
//// This file is part of the "UART 16550 compatible" project //// |
//// http://www.opencores.org/cores/uart16550/ //// |
//// //// |
//// Documentation related to this project: //// |
//// - http://www.opencores.org/cores/uart16550/ //// |
//// //// |
//// Projects compatibility: //// |
//// - WISHBONE //// |
//// RS232 Protocol //// |
//// 16550D uart (mostly supported) //// |
//// //// |
//// Overview (main Features): //// |
//// Defines of the Core //// |
//// //// |
//// Known problems (limits): //// |
//// None //// |
//// //// |
//// To Do: //// |
//// Nothing. //// |
//// //// |
//// Author(s): //// |
//// - gorban@opencores.org //// |
//// - Jacob Gorban //// |
//// - Igor Mohor (igorm@opencores.org) //// |
//// //// |
//// Created: 2001/05/12 //// |
//// Last Updated: 2001/05/17 //// |
//// (See log for the revision history) //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000, 2001 Authors //// |
//// //// |
//// 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 $ |
// Revision 1.13 2003/06/11 16:37:47 gorban |
// This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended. |
// |
// Revision 1.12 2002/07/22 23:02:23 gorban |
// Bug Fixes: |
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed. |
// Problem reported by Kenny.Tung. |
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers. |
// |
// Improvements: |
// * Made FIFO's as general inferrable memory where possible. |
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx). |
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times. |
// |
// * Added optional baudrate output (baud_o). |
// This is identical to BAUDOUT* signal on 16550 chip. |
// It outputs 16xbit_clock_rate - the divided clock. |
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use. |
// |
// Revision 1.10 2001/12/11 08:55:40 mohor |
// Scratch register define added. |
// |
// Revision 1.9 2001/12/03 21:44:29 gorban |
// Updated specification documentation. |
// Added full 32-bit data bus interface, now as default. |
// Address is 5-bit wide in 32-bit data bus mode. |
// Added wb_sel_i input to the core. It's used in the 32-bit mode. |
// Added debug interface with two 32-bit read-only registers in 32-bit mode. |
// Bits 5 and 6 of LSR are now only cleared on TX FIFO write. |
// My small test bench is modified to work with 32-bit mode. |
// |
// Revision 1.8 2001/11/26 21:38:54 gorban |
// Lots of fixes: |
// Break condition wasn't handled correctly at all. |
// LSR bits could lose their values. |
// LSR value after reset was wrong. |
// Timing of THRE interrupt signal corrected. |
// LSR bit 0 timing corrected. |
// |
// Revision 1.7 2001/08/24 21:01:12 mohor |
// Things connected to parity changed. |
// Clock devider changed. |
// |
// Revision 1.6 2001/08/23 16:05:05 mohor |
// Stop bit bug fixed. |
// Parity bug fixed. |
// WISHBONE read cycle bug fixed, |
// OE indicator (Overrun Error) bug fixed. |
// PE indicator (Parity Error) bug fixed. |
// Register read bug fixed. |
// |
// Revision 1.5 2001/05/31 20:08:01 gorban |
// FIFO changes and other corrections. |
// |
// Revision 1.4 2001/05/21 19:12:02 gorban |
// Corrected some Linter messages. |
// |
// Revision 1.3 2001/05/17 18:34:18 gorban |
// First 'stable' release. Should be sythesizable now. Also added new header. |
// |
// Revision 1.0 2001-05-17 21:27:11+02 jacob |
// Initial revision |
// |
// |
|
// remove comments to restore to use the new version with 8 data bit interface |
// in 32bit-bus mode, the wb_sel_i signal is used to put data in correct place |
// also, in 8-bit version there'll be no debugging features included |
// CAUTION: doesn't work with current version of OR1200 |
`define DATA_BUS_WIDTH_8 |
|
`ifdef DATA_BUS_WIDTH_8 |
`define UART_ADDR_WIDTH 3 |
`define UART_DATA_WIDTH 8 |
`else |
`define UART_ADDR_WIDTH 5 |
`define UART_DATA_WIDTH 32 |
`endif |
|
// Uncomment this if you want your UART to have |
// 16xBaudrate output port. |
// If defined, the enable signal will be used to drive baudrate_o signal |
// It's frequency is 16xbaudrate |
|
// `define UART_HAS_BAUDRATE_OUTPUT |
|
// Register addresses |
`define UART_REG_RB `UART_ADDR_WIDTH'd0 // receiver buffer |
`define UART_REG_TR `UART_ADDR_WIDTH'd0 // transmitter |
`define UART_REG_IE `UART_ADDR_WIDTH'd1 // Interrupt enable |
`define UART_REG_II `UART_ADDR_WIDTH'd2 // Interrupt identification |
`define UART_REG_FC `UART_ADDR_WIDTH'd2 // FIFO control |
`define UART_REG_LC `UART_ADDR_WIDTH'd3 // Line Control |
`define UART_REG_MC `UART_ADDR_WIDTH'd4 // Modem control |
`define UART_REG_LS `UART_ADDR_WIDTH'd5 // Line status |
`define UART_REG_MS `UART_ADDR_WIDTH'd6 // Modem status |
`define UART_REG_SR `UART_ADDR_WIDTH'd7 // Scratch register |
`define UART_REG_DL1 `UART_ADDR_WIDTH'd0 // Divisor latch bytes (1-2) |
`define UART_REG_DL2 `UART_ADDR_WIDTH'd1 |
|
// Interrupt Enable register bits |
`define UART_IE_RDA 0 // Received Data available interrupt |
`define UART_IE_THRE 1 // Transmitter Holding Register empty interrupt |
`define UART_IE_RLS 2 // Receiver Line Status Interrupt |
`define UART_IE_MS 3 // Modem Status Interrupt |
|
// Interrupt Identification register bits |
`define UART_II_IP 0 // Interrupt pending when 0 |
`define UART_II_II 3:1 // Interrupt identification |
|
// Interrupt identification values for bits 3:1 |
`define UART_II_RLS 3'b011 // Receiver Line Status |
`define UART_II_RDA 3'b010 // Receiver Data available |
`define UART_II_TI 3'b110 // Timeout Indication |
`define UART_II_THRE 3'b001 // Transmitter Holding Register empty |
`define UART_II_MS 3'b000 // Modem Status |
|
// FIFO Control Register bits |
`define UART_FC_TL 1:0 // Trigger level |
|
// FIFO trigger level values |
`define UART_FC_1 2'b00 |
`define UART_FC_4 2'b01 |
`define UART_FC_8 2'b10 |
`define UART_FC_14 2'b11 |
|
// Line Control register bits |
`define UART_LC_BITS 1:0 // bits in character |
`define UART_LC_SB 2 // stop bits |
`define UART_LC_PE 3 // parity enable |
`define UART_LC_EP 4 // even parity |
`define UART_LC_SP 5 // stick parity |
`define UART_LC_BC 6 // Break control |
`define UART_LC_DL 7 // Divisor Latch access bit |
|
// Modem Control register bits |
`define UART_MC_DTR 0 |
`define UART_MC_RTS 1 |
`define UART_MC_OUT1 2 |
`define UART_MC_OUT2 3 |
`define UART_MC_LB 4 // Loopback mode |
|
// Line Status Register bits |
`define UART_LS_DR 0 // Data ready |
`define UART_LS_OE 1 // Overrun Error |
`define UART_LS_PE 2 // Parity Error |
`define UART_LS_FE 3 // Framing Error |
`define UART_LS_BI 4 // Break interrupt |
`define UART_LS_TFE 5 // Transmit FIFO is empty |
`define UART_LS_TE 6 // Transmitter Empty indicator |
`define UART_LS_EI 7 // Error indicator |
|
// Modem Status Register bits |
`define UART_MS_DCTS 0 // Delta signals |
`define UART_MS_DDSR 1 |
`define UART_MS_TERI 2 |
`define UART_MS_DDCD 3 |
`define UART_MS_CCTS 4 // Complement signals |
`define UART_MS_CDSR 5 |
`define UART_MS_CRI 6 |
`define UART_MS_CDCD 7 |
|
// FIFO parameter defines |
|
`define UART_FIFO_WIDTH 8 |
`define UART_FIFO_DEPTH 16 |
`define UART_FIFO_POINTER_W 4 |
`define UART_FIFO_COUNTER_W 5 |
// receiver fifo has width 11 because it has break, parity and framing error bits |
`define UART_FIFO_REC_WIDTH 11 |
|
|
`define VERBOSE_WB 0 // All activity on the WISHBONE is recorded |
`define VERBOSE_LINE_STATUS 0 // Details about the lsr (line status register) |
`define FAST_TEST 1 // 64/1024 packets are sent |
|
// Defines hard baud prescaler register - uncomment to enable |
//`define PRESCALER_PRESET_HARD |
// 115200 baud preset values |
// 20MHz: prescaler 10.8 (11, rounded up) |
//`define PRESCALER_HIGH_PRESET 8'd0 |
//`define PRESCALER_LOW_PRESET 8'd11 |
// 50MHz: prescaler 27.1 |
//`define PRESCALER_HIGH_PRESET 8'd0 |
//`define PRESCALER_LOW_PRESET 8'd27 |
// 66MHz: prescaler 36.1 |
//`define PRESCALER_HIGH_PRESET 8'd0 |
//`define PRESCALER_LOW_PRESET 8'd36 |
|
/s3adsp1800/rtl/verilog/include/dbg_defines.v
0,0 → 1,153
////////////////////////////////////////////////////////////////////// |
//// //// |
//// dbg_defines.v //// |
//// //// |
//// //// |
//// This file is part of the SoC Debug Interface. //// |
//// http://www.opencores.org/projects/DebugInterface/ //// |
//// //// |
//// Author(s): //// |
//// Igor Mohor (igorm@opencores.org) //// |
//// //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 - 2004 Authors //// |
//// //// |
//// 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: dbg_defines.v,v $ |
// Revision 1.20 2004/04/01 11:56:59 igorm |
// Port names and defines for the supported CPUs changed. |
// |
// Revision 1.19 2004/03/28 20:27:02 igorm |
// New release of the debug interface (3rd. release). |
// |
// Revision 1.18 2004/03/22 16:35:46 igorm |
// Temp version before changing dbg interface. |
// |
// Revision 1.17 2004/01/30 10:24:30 mohor |
// Defines WISHBONE_SUPPORTED and CPU_SUPPORTED added. By default both are |
// turned on. |
// |
// Revision 1.16 2004/01/20 14:23:45 mohor |
// Define name changed. |
// |
// Revision 1.15 2003/12/23 15:07:34 mohor |
// New directory structure. New version of the debug interface. |
// Files that are not needed removed. |
// |
// Revision 1.14 2003/10/23 16:17:00 mohor |
// CRC logic changed. |
// |
// Revision 1.13 2003/10/21 09:48:31 simons |
// Mbist support added. |
// |
// Revision 1.12 2003/09/17 14:38:57 simons |
// WB_CNTL register added, some syncronization fixes. |
// |
// Revision 1.11 2003/08/28 13:55:21 simons |
// Three more chains added for cpu debug access. |
// |
// Revision 1.10 2003/07/31 12:19:49 simons |
// Multiple cpu support added. |
// |
// Revision 1.9 2002/05/07 14:43:59 mohor |
// mon_cntl_o signals that controls monitor mux added. |
// |
// Revision 1.8 2002/01/25 07:58:34 mohor |
// IDCODE bug fixed, chains reused to decreas size of core. Data is shifted-in |
// not filled-in. Tested in hw. |
// |
// Revision 1.7 2001/12/06 10:08:06 mohor |
// Warnings from synthesys tools fixed. |
// |
// Revision 1.6 2001/11/28 09:38:30 mohor |
// Trace disabled by default. |
// |
// Revision 1.5 2001/10/15 09:55:47 mohor |
// Wishbone interface added, few fixes for better performance, |
// hooks for boundary scan testing added. |
// |
// Revision 1.4 2001/09/24 14:06:42 mohor |
// Changes connected to the OpenRISC access (SPR read, SPR write). |
// |
// Revision 1.3 2001/09/20 10:11:25 mohor |
// Working version. Few bugs fixed, comments added. |
// |
// Revision 1.2 2001/09/18 14:13:47 mohor |
// Trace fixed. Some registers changed, trace simplified. |
// |
// Revision 1.1.1.1 2001/09/13 13:49:19 mohor |
// Initial official release. |
// |
// Revision 1.3 2001/06/01 22:22:35 mohor |
// This is a backup. It is not a fully working version. Not for use, yet. |
// |
// Revision 1.2 2001/05/18 13:10:00 mohor |
// Headers changed. All additional information is now avaliable in the README.txt file. |
// |
// Revision 1.1.1.1 2001/05/18 06:35:08 mohor |
// Initial release |
// |
// |
|
|
// Length of the MODULE ID register |
`define DBG_TOP_MODULE_ID_LENGTH 4 |
|
// Length of data |
`define DBG_TOP_MODULE_DATA_LEN `DBG_TOP_MODULE_ID_LENGTH + 1 |
`define DBG_TOP_DATA_CNT 3 |
|
// Length of status |
`define DBG_TOP_STATUS_LEN 3'd4 |
`define DBG_TOP_STATUS_CNT_WIDTH 3 |
|
// Length of the CRC |
`define DBG_TOP_CRC_LEN 32 |
`define DBG_TOP_CRC_CNT 6 |
|
// Chains |
`define DBG_TOP_WISHBONE_DEBUG_MODULE 4'h0 |
`define DBG_TOP_CPU0_DEBUG_MODULE 4'h1 |
`define DBG_TOP_CPU1_DEBUG_MODULE 4'h2 |
|
// If WISHBONE sub-module is supported uncomment the folowing line |
`define DBG_WISHBONE_SUPPORTED |
|
// If CPU_0 sub-module is supported uncomment the folowing line |
`define DBG_CPU0_SUPPORTED |
|
// If CPU_1 sub-module is supported uncomment the folowing line |
//`define DBG_CPU1_SUPPORTED |
|
// If more debug info is needed, uncomment the follofing line |
//`define DBG_MORE_INFO |
|
/s3adsp1800/rtl/verilog/include/s3adsp_ddr2_parameters_0.v
0,0 → 1,91
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_parameters_0.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:42 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This module has the parameters used in the design |
//***************************************************************************** |
|
//`timescale 1ns/100ps |
|
// The reset polarity is set to active low by default. |
// You can change this by editing the parameter RESET_ACTIVE_LOW. |
// Please do not change any of the other parameters directly by editing the RTL. |
// All other changes should be done through the GUI. |
|
`define DATA_WIDTH 32 |
`define DATA_STROBE_WIDTH 4 |
`define DATA_MASK_WIDTH 4 |
`define CLK_WIDTH 2 |
`define CKE_WIDTH 1 |
`define ROW_ADDRESS 13 |
`define MEMORY_WIDTH 8 |
`define REGISTERED 0 |
`define DATABITSPERSTROBE 8 |
`define RESET_PORT 0 |
`define MASK_ENABLE 1 |
`define USE_DM_PORT 1 |
`define COLUMN_ADDRESS 10 |
`define BANK_ADDRESS 2 |
`define DEBUG_EN 0 |
`define CLK_TYPE "SINGLE_ENDED" |
`define LOAD_MODE_REGISTER 13'b0010100110011 |
`define EXT_LOAD_MODE_REGISTER 13'b0000000000000 |
`define RESET_ACTIVE_LOW 1'b1 |
`define RAS_COUNT_VALUE 5'b00101 |
`define RP_COUNT_VALUE 3'b001 |
`define RFC_COUNT_VALUE 8'b00001101 |
`define TWR_COUNT_VALUE 3'b010 |
`define MAX_REF_WIDTH 10 |
`define MAX_REF_CNT 10'b1111100111 |
|
`include "synthesis-defines.v" |
`ifndef SYNTHESIS |
// To skip the 200us wait at simulation start |
`define simulation |
`endif |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_data_read_0.v
0,0 → 1,201
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007, 2008 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_data_read_0.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:41 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : ram8d modules are instantiated for Read data FIFOs. RAM8D is |
// each 8 bits or 4 bits depending on number data bits per strobe. |
// Each strobe will have two instances, one for rising edge data |
// and one for falling edge data. |
//***************************************************************************** |
|
`timescale 1ns/100ps |
`include "s3adsp_ddr2_parameters_0.v" |
|
|
module s3adsp_ddr2_data_read_0 |
( |
input clk90, |
input reset90, |
input [(`DATA_WIDTH-1):0] ddr_dq_in, |
input [(`DATA_STROBE_WIDTH-1):0] fifo_0_wr_en, |
input [(`DATA_STROBE_WIDTH-1):0] fifo_1_wr_en, |
input [(4*`DATA_STROBE_WIDTH)-1:0] fifo_0_wr_addr , |
input [(4*`DATA_STROBE_WIDTH)-1:0] fifo_1_wr_addr , |
input [(`DATA_STROBE_WIDTH-1):0] dqs_delayed_col0, |
input [(`DATA_STROBE_WIDTH-1):0] dqs_delayed_col1, |
input read_fifo_rden, |
output [((`DATA_WIDTH*2)-1):0] user_output_data, |
output u_data_val |
); |
|
reg reset90_r; |
|
reg [(4*`DATA_STROBE_WIDTH)-1:0] fifo0_rd_addr_r |
/* synthesis syn_preserve=1 */; |
reg [(4*`DATA_STROBE_WIDTH)-1:0] fifo1_rd_addr_r |
/* synthesis syn_preserve=1 */; |
|
reg [`DATA_WIDTH-1:0] fifo_0_data_out_r |
/* synthesis syn_preserve=1 */; |
reg [`DATA_WIDTH-1:0] fifo_1_data_out_r |
/* synthesis syn_preserve=1 */; |
|
reg [((`DATA_WIDTH*2)-1):0] first_sdr_data; |
reg read_fifo_rden_90r1; |
reg read_fifo_rden_90r2; |
reg read_fifo_rden_90r3; |
reg read_fifo_rden_90r4; |
reg read_fifo_rden_90r5; |
reg read_fifo_rden_90r6; |
|
wire [3:0] fifo0_rd_addr; |
wire [3:0] fifo1_rd_addr; |
wire [`DATA_WIDTH-1:0] fifo_0_data_out; |
wire [`DATA_WIDTH-1:0] fifo_1_data_out; |
wire [(`DATA_STROBE_WIDTH-1):0] dqs_delayed_col0_n; |
wire [(`DATA_STROBE_WIDTH-1):0] dqs_delayed_col1_n; |
|
|
assign dqs_delayed_col0_n = ~ dqs_delayed_col0; |
assign dqs_delayed_col1_n = ~ dqs_delayed_col1; |
assign user_output_data = first_sdr_data; |
assign u_data_val = read_fifo_rden_90r6; |
|
|
always @( posedge clk90 ) |
reset90_r <= reset90; |
|
// Read fifo read enable signal phase is changed from 180 to 90 clock domain |
always@(posedge clk90) begin |
if(reset90_r)begin |
read_fifo_rden_90r1 <= 1'b0; |
read_fifo_rden_90r2 <= 1'b0; |
read_fifo_rden_90r3 <= 1'b0; |
read_fifo_rden_90r4 <= 1'b0; |
read_fifo_rden_90r5 <= 1'b0; |
read_fifo_rden_90r6 <= 1'b0; |
|
end |
else begin |
read_fifo_rden_90r1 <= read_fifo_rden; |
read_fifo_rden_90r2 <= read_fifo_rden_90r1; |
read_fifo_rden_90r3 <= read_fifo_rden_90r2; |
read_fifo_rden_90r4 <= read_fifo_rden_90r3; |
read_fifo_rden_90r5 <= read_fifo_rden_90r4; |
read_fifo_rden_90r6 <= read_fifo_rden_90r5; |
end |
end |
|
always@(posedge clk90) begin |
fifo_0_data_out_r <= fifo_0_data_out; |
fifo_1_data_out_r <= fifo_1_data_out; |
end |
|
genvar addr_i; |
generate for(addr_i = 0; addr_i < `DATA_STROBE_WIDTH; addr_i = addr_i + 1) begin: gen_rd_addr |
always@(posedge clk90) begin |
fifo0_rd_addr_r[addr_i*4+:4] <= fifo0_rd_addr; |
fifo1_rd_addr_r[addr_i*4+:4] <= fifo1_rd_addr; |
end |
end |
endgenerate |
always@(posedge clk90)begin |
if(reset90_r) |
first_sdr_data <= {(`DATA_WIDTH*2){1'b0}}; |
else if(read_fifo_rden_90r5) |
first_sdr_data <= {fifo_0_data_out_r, fifo_1_data_out_r}; |
end |
|
|
s3adsp_ddr2_rd_gray_cntr fifo0_rd_addr_inst |
( |
.clk90 (clk90), |
.reset90 (reset90), |
.cnt_en (read_fifo_rden_90r3), |
.rgc_gcnt (fifo0_rd_addr) |
); |
|
s3adsp_ddr2_rd_gray_cntr fifo1_rd_addr_inst |
( |
.clk90 (clk90), |
.reset90 (reset90), |
.cnt_en (read_fifo_rden_90r3), |
.rgc_gcnt (fifo1_rd_addr) |
); |
|
|
|
genvar strobe_i; |
generate for(strobe_i = 0; strobe_i < `DATA_STROBE_WIDTH; strobe_i = strobe_i + 1) |
begin: gen_strobe |
s3adsp_ddr2_ram8d_0 strobe |
( |
.dout (fifo_0_data_out[strobe_i*`DATABITSPERSTROBE+:`DATABITSPERSTROBE]), |
.waddr (fifo_0_wr_addr[strobe_i*4+:4]), |
.din (ddr_dq_in[strobe_i*`DATABITSPERSTROBE+:`DATABITSPERSTROBE]), |
.raddr (fifo0_rd_addr_r[strobe_i*4+:4]), |
.wclk0 (dqs_delayed_col0[strobe_i]), |
.wclk1 (dqs_delayed_col1[strobe_i]), |
.we (fifo_0_wr_en[strobe_i]) |
); |
|
s3adsp_ddr2_ram8d_0 strobe_n |
( |
.dout (fifo_1_data_out[strobe_i*`DATABITSPERSTROBE+:`DATABITSPERSTROBE]), |
.waddr (fifo_1_wr_addr[strobe_i*4+:4]), |
.din (ddr_dq_in[strobe_i*`DATABITSPERSTROBE+:`DATABITSPERSTROBE]), |
.raddr (fifo1_rd_addr_r[strobe_i*4+:4]), |
.wclk0 (dqs_delayed_col0_n[strobe_i]), |
.wclk1 (dqs_delayed_col1_n[strobe_i]), |
.we (fifo_1_wr_en[strobe_i]) |
); |
end |
endgenerate |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_s3_dqs_iob.v
0,0 → 1,121
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007, 2008 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_s3_dqs_iob.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:42 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This module instantiates DDR IOB output flip-flops, an |
// output buffer with registered tri-state, and an input buffer |
// for a single strobe/dqs bit. The DDR IOB output flip-flops |
// are used to forward strobe to memory during a write. During |
// a read, the output of the IBUF is routed to the internal |
// delay module, dqs_delay. |
//***************************************************************************** |
|
`timescale 1ns/100ps |
module s3adsp_ddr2_s3_dqs_iob |
( |
input clk, |
input ddr_dqs_reset, |
input ddr_dqs_enable, |
inout ddr_dqs, |
inout ddr_dqs_n, |
output dqs |
); |
|
localparam VCC = 1'b1; |
localparam GND = 1'b0; |
|
wire dqs_q; |
wire ddr_dqs_enable1; |
wire ddr_dqs_enable_b; |
wire data1; |
|
assign ddr_dqs_enable_b = ~ddr_dqs_enable; |
assign data1 = (ddr_dqs_reset == 1'b1) ? 1'b0 : 1'b1; |
|
|
(* IOB = "FORCE" *) FD U1 |
( |
.D(ddr_dqs_enable_b), |
.Q(ddr_dqs_enable1), |
.C(clk) |
)/* synthesis syn_useioff = 1 */; |
|
FDDRRSE U2 ( |
.Q(dqs_q), |
.C0(clk), |
.C1(~clk), |
.CE(VCC), |
.D0(data1), |
.D1(GND), |
.R(GND), |
.S(GND) |
); |
|
|
|
|
//*********************************************************************** |
//IO buffer for dqs signal. Allows for distribution of dqsto the data(DQ) loads. |
//*********************************************************************** |
|
|
OBUFTDS U3 ( |
.I(dqs_q), |
.T(ddr_dqs_enable1), |
.O(ddr_dqs), |
.OB(ddr_dqs_n) |
); |
|
IBUFDS U4 ( |
.I(ddr_dqs), |
.IB(ddr_dqs_n), |
.O(dqs) |
); |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_data_read_controller_0.v
0,0 → 1,202
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007, 2008 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_data_read_controller_0.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:41 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This module has instantiations fifo_0_wr_en, fifo_1_wr_en, |
// dqs_delay and wr_gray_cntr. |
//***************************************************************************** |
|
`timescale 1ns/100ps |
`include "s3adsp_ddr2_parameters_0.v" |
|
module s3adsp_ddr2_data_read_controller_0 |
( |
input clk, |
input reset, |
input rst_dqs_div_in, |
input [4:0] delay_sel, |
input [(`DATA_STROBE_WIDTH-1):0] dqs_int_delay_in, |
output [(`DATA_STROBE_WIDTH-1):0] fifo_0_wr_en_val, |
output [(`DATA_STROBE_WIDTH-1):0] fifo_1_wr_en_val, |
output [(4*`DATA_STROBE_WIDTH)-1:0] fifo_0_wr_addr_val, |
output [(4*`DATA_STROBE_WIDTH)-1:0] fifo_1_wr_addr_val, |
output [(`DATA_STROBE_WIDTH-1):0] dqs_delayed_col0_val, |
output [(`DATA_STROBE_WIDTH-1):0] dqs_delayed_col1_val, |
//debug_signals |
input [4:0] vio_out_dqs, |
input vio_out_dqs_en, |
input [4:0] vio_out_rst_dqs_div, |
input vio_out_rst_dqs_div_en |
|
); |
|
reg reset_r; |
wire rst_dqs_div; |
wire [(4*`DATA_STROBE_WIDTH)-1:0] fifo_0_wr_addr; |
wire [(4*`DATA_STROBE_WIDTH)-1:0] fifo_1_wr_addr; |
wire [(`DATA_STROBE_WIDTH-1):0] rst_dqs_delay_n; |
wire [(`DATA_STROBE_WIDTH-1):0] dqs_delayed_col0_n; |
wire [(`DATA_STROBE_WIDTH-1):0] dqs_delayed_col1_n; |
wire [(`DATA_STROBE_WIDTH-1):0] fifo_0_wr_en/* synthesis syn_keep=1 */; |
wire [(`DATA_STROBE_WIDTH-1):0] fifo_1_wr_en/* synthesis syn_keep=1 */; |
wire [4:0] delay_sel_rst_dqs_div; |
wire [4:0] delay_sel_dqs; |
|
(* BUFFER_TYPE = "none" *) wire [(`DATA_STROBE_WIDTH-1):0] dqs_delayed_col0; |
(* BUFFER_TYPE = "none" *) wire [(`DATA_STROBE_WIDTH-1):0] dqs_delayed_col1; |
|
assign fifo_0_wr_addr_val = fifo_0_wr_addr; |
assign fifo_1_wr_addr_val = fifo_1_wr_addr; |
assign fifo_0_wr_en_val = fifo_0_wr_en; |
assign fifo_1_wr_en_val = fifo_1_wr_en; |
assign dqs_delayed_col0_val = dqs_delayed_col0; |
assign dqs_delayed_col1_val = dqs_delayed_col1; |
assign dqs_delayed_col0_n = ~ dqs_delayed_col0; |
assign dqs_delayed_col1_n = ~ dqs_delayed_col1; |
|
|
always @(posedge clk) |
reset_r <= reset; |
|
|
generate |
if(`DEBUG_EN) |
assign delay_sel_rst_dqs_div = (vio_out_rst_dqs_div_en) ? |
vio_out_rst_dqs_div[4:0] : |
delay_sel; |
else |
assign delay_sel_rst_dqs_div = delay_sel; |
endgenerate |
|
// rst_dqs_div instantation. |
s3adsp_ddr2_dqs_delay rst_dqs_div_delayed |
( |
.clk_in(rst_dqs_div_in), |
.sel_in(delay_sel_rst_dqs_div), |
.clk_out(rst_dqs_div) |
); |
|
|
generate |
if(`DEBUG_EN) |
assign delay_sel_dqs = vio_out_dqs_en ? vio_out_dqs[4:0] : delay_sel; |
else |
assign delay_sel_dqs = delay_sel; |
endgenerate |
|
|
//DQS Internal Delay Circuit implemented in LUTs |
genvar dly_i; |
generate |
for(dly_i = 0; dly_i < `DATA_STROBE_WIDTH; dly_i = dly_i + 1) |
begin: gen_delay |
s3adsp_ddr2_dqs_delay dqs_delay_col0 |
( |
.clk_in (dqs_int_delay_in[dly_i]), |
.sel_in (delay_sel_dqs), |
.clk_out (dqs_delayed_col0[dly_i]) |
)/* synthesis syn_preserve=1 */; |
|
s3adsp_ddr2_dqs_delay dqs_delay_col1 |
( |
.clk_in (dqs_int_delay_in[dly_i]), |
.sel_in (delay_sel_dqs), |
.clk_out (dqs_delayed_col1[dly_i]) |
)/* synthesis syn_preserve=1 */; |
end |
endgenerate |
|
|
// FIFO write enables instances |
genvar wren_i; |
generate |
for(wren_i = 0; wren_i < `DATA_STROBE_WIDTH; wren_i = wren_i + 1) |
begin: gen_wr_en |
s3adsp_ddr2_fifo_0_wr_en_0 fifo_0_wr_en_inst |
( |
.clk (dqs_delayed_col1_n [wren_i]), |
.reset (reset_r), |
.din (rst_dqs_div), |
.rst_dqs_delay_n (rst_dqs_delay_n[wren_i]), |
.dout (fifo_0_wr_en[wren_i]) |
); |
s3adsp_ddr2_fifo_1_wr_en_0 fifo_1_wr_en_inst |
( |
.clk (dqs_delayed_col0[wren_i]), |
.rst_dqs_delay_n (rst_dqs_delay_n[wren_i]), |
.reset (reset_r), |
.din (rst_dqs_div), |
.dout (fifo_1_wr_en[wren_i]) |
); |
end |
endgenerate |
|
//FIFO write pointer instances |
genvar wr_addr_i; |
generate |
for(wr_addr_i = 0; wr_addr_i < `DATA_STROBE_WIDTH; wr_addr_i = wr_addr_i + 1) |
begin: gen_wr_addr |
s3adsp_ddr2_wr_gray_cntr fifo_0_wr_addr_inst |
( |
.clk (dqs_delayed_col1[wr_addr_i]), |
.reset (reset_r), |
.cnt_en (fifo_0_wr_en[wr_addr_i]), |
.wgc_gcnt (fifo_0_wr_addr[wr_addr_i*4+:4]) |
); |
s3adsp_ddr2_wr_gray_cntr fifo_1_wr_addr_inst |
( |
.clk (dqs_delayed_col0_n[wr_addr_i]), |
.reset (reset_r), |
.cnt_en (fifo_1_wr_en[wr_addr_i]), |
.wgc_gcnt (fifo_1_wr_addr[wr_addr_i*4+:4]) |
); |
end |
endgenerate |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/xilinx_s3adsp_ddr2_if.v
0,0 → 1,1082
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Xilinx Spartan 3A DSP DDR2 controller from MIG //// |
//// //// |
//// Description //// |
//// //// |
//// To Do: //// |
//// Employ LRU replacement scheme //// |
//// Remove hard-coding of things relating to number of lines //// |
//// //// |
//// Author(s): //// |
//// - Julius Baxter, julius@opencores.org //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2011 Authors and 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// Cache generated by coregen, uses 2x18kbit block RAMS, or 4KByte |
// Currently only using 4 lines x 8 words * 32-bits (4bytes) = 128 bytes |
// Could potentially have up to (4096/(8*4)) 128 lines. |
|
// Addressing for DDR2 interface is as follows. |
// SDRAM is 128MB, so up to 0x08000000 (28 bits) |
// DDR2 MIG configured in burst length of 8 (8*32 per request) |
// DDR2 MIG takes 25 bit address (row[12:0],col[9:0],ba[1:0]) |
|
// So for every address on DDR2 MIG address interface, we get 8*32-bit words |
// or (8*4) 32 bytes. 5-bits of address on the Wishbone bus. |
|
// Current setting is just 4-lines of cache with 8-words per line |
// We'll have 3-bits for words in the line. |
// Tag will be 28-3-2 (final 2 is due to 4-bytes per word) so 23-bits. |
|
// So address to the DDR2 interface should be the 23 bits of tag, and 2'b00 |
// for the 4 column addresses we burst over. |
|
|
module xilinx_s3adsp_ddr2_if ( |
input [31:0] wb_adr_i, |
input wb_stb_i, |
input wb_cyc_i, |
input [2:0] wb_cti_i, |
input [1:0] wb_bte_i, |
input wb_we_i, |
input [3:0] wb_sel_i, |
input [31:0] wb_dat_i, |
output [31:0] wb_dat_o, |
output reg wb_ack_o, |
|
inout [31:0] ddr2_dq, |
output [12:0] ddr2_a, |
output [1:0] ddr2_ba, |
output ddr2_cke, |
output ddr2_cs_n, |
output ddr2_ras_n, |
output ddr2_cas_n, |
output ddr2_we_n, |
output ddr2_odt, |
output [3:0] ddr2_dm, |
inout [3:0] ddr2_dqs, |
inout [3:0] ddr2_dqs_n, |
output [1:0] ddr2_ck, |
output [1:0] ddr2_ck_n, |
input ddr2_rst_dqs_div_in, |
output ddr2_rst_dqs_div_out, |
input clk133_i, |
|
input wb_clk, |
input wb_rst); |
|
|
// 128MB, so 0x800_0000 |
`define ADDR_BIT_MAX 28 |
|
/* |
`define DDR2_CACHE_NUM_LINES 16 |
`define DDR2_CACHE_NUM_LINES_ENC_WIDTH 4 // log2(`DDR2_CACHE_NUM_LINES) |
*/ |
|
`define DDR2_CACHE_NUM_LINES 4 |
`define DDR2_CACHE_NUM_LINES_ENC_WIDTH 2 // log2(`DDR2_CACHE_NUM_LINES) |
|
|
//`define DDR2_CACHE_NUM_LINES 32 |
//`define DDR2_CACHE_NUM_LINES_ENC_WIDTH 5 // log2(`DDR2_CACHE_NUM_LINES) |
|
|
`define DDR2_CACHE_NUM_WORDS_PER_LINE 8 |
`define DDR2_CACHE_ADDR_WIDTH_WORDS_PER_LINE 3 |
`define DDR2_CACHE_TAG_ADDR_WIDTH (32-`DDR2_CACHE_ADDR_WIDTH_WORDS_PER_LINE-2) |
|
`define DDR2_CACHE_DDR2_SIDE_NUM_WORDS_PER_LINE (`DDR2_CACHE_NUM_WORDS_PER_LINE/2) |
`define DDR2_CACHE_DDR2_SIDE_ADDR_WIDTH_NUM_WORDS_PER_LINE (`DDR2_CACHE_ADDR_WIDTH_WORDS_PER_LINE - 1) |
`define DDR2_CACHE_DDR2_SIDE_ADDR_WIDTH (`DDR2_CACHE_NUM_LINES_ENC_WIDTH + `DDR2_CACHE_DDR2_SIDE_ADDR_WIDTH_NUM_WORDS_PER_LINE) |
|
`define BYTES_PER_WORD 4 |
`define BYTES_PER_WORD_ADDR_WIDTH 2 |
|
// Board has 128MB of memory, so highest address is 27'h7ff_ffff |
`define DDR2_CACHE_TAG_BITS (`ADDR_BIT_MAX-1):(`DDR2_CACHE_ADDR_WIDTH_WORDS_PER_LINE + \ |
`BYTES_PER_WORD_ADDR_WIDTH) |
|
|
wire wb_req; |
reg wb_req_r; |
reg wb_ack_o_r; |
|
wire wb_req_new; |
reg wb_req_new_r; |
|
wire wb_req_addr_hit; |
|
wire cached_addr_valid; |
|
|
wire [`DDR2_CACHE_TAG_BITS] cache_line_tag; |
|
wire cache_write; |
|
wire cache_hit; |
|
wire wb_cache_en; |
|
reg do_writeback; |
|
reg do_readfrom; |
reg do_readfrom_ddr2_sync, do_readfrom_ddr2_sync2, |
do_readfrom_ddr2_sync3; |
wire do_readfrom_start_ddr2; |
|
reg do_writeback_ddr2_sync, do_writeback_ddr2_sync2, |
do_writeback_ddr2_sync3; |
wire do_writeback_start_ddr2; |
|
reg ddr2_readfrom_done; |
reg wb_readfrom_done_sync,wb_readfrom_done_sync2; |
wire wb_readfrom_done; |
|
reg ddr2_writeback_done; |
reg wb_writeback_done_sync,wb_writeback_done_sync2; |
wire wb_writeback_done; |
|
reg ddr2_readfrom_done_wb_sync, ddr2_readfrom_done_wb_sync2; |
reg ddr2_writeback_done_wb_sync, ddr2_writeback_done_wb_sync2; |
|
|
wire ddr2_if_clk_90; |
wire ddr2_if_clk; |
wire ddr2_rst, ddr2_rst_90, ddr2_rst_180; |
reg [24:0] ddr2_if_input_address; |
wire [63:0] ddr2_if_wdata; |
wire [63:0] ddr2_if_rdata; |
wire ddr2_if_rdata_valid; |
reg [2:0] ddr2_if_cmd; |
|
wire ddr2_if_ref_req, ddr2_if_cmd_ack; |
wire ddr2_if_af_done, ddr2_if_burst_done; |
reg ddr2_if_init_sent; |
|
|
// [0] - Waiting for ddr2_if_cmd_ack |
// [4:1] - data0-data3 out from RAM |
// [8:5] - ddr2_if_burst_done high for 4 cycles |
// [9] - finish |
reg [9:0] ddr2_write_state_shr; |
|
// [0] - waiting for ddr2_if_cmd_ack |
// [4:1] - asserting ddr2_if_burst_done |
// [5] - waiting for ddr2_if_cmd_ack to be deasserted |
// [6] - finish |
reg [6:0] ddr2_read_state_shr; |
|
reg [4:0] ddr2_read_dv_counter_shr; |
|
|
wire phy_init_done; |
|
wire [`DDR2_CACHE_NUM_LINES - 1 :0] cache_line_addr_validate; |
wire [`DDR2_CACHE_NUM_LINES - 1 :0] cache_line_addr_invalidate; |
wire [`DDR2_CACHE_NUM_LINES - 1 :0] cache_line_addr_valid; |
wire [`DDR2_CACHE_NUM_LINES - 1 :0] cache_line_hit; |
wire [`DDR2_CACHE_TAG_BITS] cache_line_addr [0:`DDR2_CACHE_NUM_LINES-1] ; |
|
// Cache control signals |
// Wishbone side |
|
wire [3:0] wb_cache_sel_we; |
// DDR side |
wire ddr2_cache_en; |
wire [7:0] ddr2_cache_we; |
|
reg wb_bursting; // Are we bursting? |
reg [2:0] wb_burst_addr; // Burst counter, up to 8 |
wire [1:0] wb_burst_addr_4beat; |
wire [2:0] wb_burst_addr_8beat; |
wire wb_burst_addr_incr; |
wire ack_err; |
reg ack_err_r; |
|
// Synchronisation signals |
reg sync, sync_r; |
wire sync_start; |
wire sync_done; |
|
wire [`DDR2_CACHE_ADDR_WIDTH_WORDS_PER_LINE-1:0] wb_cache_word; |
|
// Decoded select line |
wire [`DDR2_CACHE_NUM_LINES-1:0] selected_cache_line; |
wire [`DDR2_CACHE_NUM_LINES_ENC_WIDTH-1:0] selected_cache_line_enc; |
reg [`DDR2_CACHE_NUM_LINES_ENC_WIDTH-1:0] selected_cache_line_enc_ddr2_if_clk; |
|
reg ddr2_cache_line_word_use_next_addr; |
wire [`DDR2_CACHE_DDR2_SIDE_ADDR_WIDTH_NUM_WORDS_PER_LINE - 1:0] ddr2_cache_line_word_addr; |
reg [`DDR2_CACHE_DDR2_SIDE_ADDR_WIDTH_NUM_WORDS_PER_LINE - 1:0] ddr2_cache_line_word_addr_r; |
wire [`DDR2_CACHE_DDR2_SIDE_ADDR_WIDTH_NUM_WORDS_PER_LINE - 1:0] ddr2_cache_line_word_addr_next; |
|
|
genvar i; |
generate |
for (i=0;i<`DDR2_CACHE_NUM_LINES;i=i+1) begin : cache_addr |
ddr2_wb_if_cache_addr_reg |
#(.full_addr_width(28), // 128MB |
.line_addr_width(`DDR2_CACHE_ADDR_WIDTH_WORDS_PER_LINE)) |
cache_addr_reg_inst |
( .addr_i(wb_adr_i[`DDR2_CACHE_TAG_BITS]), |
.validate(cache_line_addr_validate[i]), |
.invalidate(cache_line_addr_invalidate[i]), |
.cache_hit(cache_line_hit[i]), |
.addr_valid(cache_line_addr_valid[i]), |
.cached_addr_o(cache_line_addr[i]), |
.clk(wb_clk), |
.rst(wb_rst)); |
end |
endgenerate |
|
wire start_writeback, start_fill; |
|
ddr2_wb_if_cache_control ddr2_wb_if_cache_control0 |
( |
// Outputs |
.start_writeback (start_writeback), |
.start_fill (start_fill), |
.cache_line_validate (cache_line_addr_validate), |
.cache_line_invalidate (cache_line_addr_invalidate), |
.selected_cache_line (selected_cache_line), |
.selected_cache_line_enc (selected_cache_line_enc), |
.sync_done (sync_done), |
// Inputs |
.cache_line_addr_valid (cache_line_addr_valid), |
.cache_line_addr_hit (cache_line_hit), |
.wb_req (wb_req), |
.cache_write (cache_write), |
.writeback_done (wb_writeback_done), |
.fill_done (wb_readfrom_done), |
.sync_start (sync_start), |
.wb_clk (wb_clk), |
.wb_rst (wb_rst)); |
|
defparam ddr2_wb_if_cache_control0.num_lines = `DDR2_CACHE_NUM_LINES; |
defparam ddr2_wb_if_cache_control0.num_lines_log2 = `DDR2_CACHE_NUM_LINES_ENC_WIDTH; |
|
assign cache_line_tag = selected_cache_line[0] ? cache_line_addr[0] : |
selected_cache_line[1] ? cache_line_addr[1] : |
selected_cache_line[2] ? cache_line_addr[2] : |
selected_cache_line[3] ? cache_line_addr[3] : |
/* |
selected_cache_line[4] ? cache_line_addr[4] : |
selected_cache_line[5] ? cache_line_addr[5] : |
selected_cache_line[6] ? cache_line_addr[6] : |
selected_cache_line[7] ? cache_line_addr[7] : |
selected_cache_line[8] ? cache_line_addr[8] : |
selected_cache_line[9] ? cache_line_addr[9] : |
selected_cache_line[10] ? cache_line_addr[10] : |
selected_cache_line[11] ? cache_line_addr[11] : |
selected_cache_line[12] ? cache_line_addr[12] : |
selected_cache_line[13] ? cache_line_addr[13] : |
selected_cache_line[14] ? cache_line_addr[14] : |
selected_cache_line[15] ? cache_line_addr[15] : |
selected_cache_line[16] ? cache_line_addr[16] : |
selected_cache_line[17] ? cache_line_addr[17] : |
selected_cache_line[18] ? cache_line_addr[18] : |
selected_cache_line[19] ? cache_line_addr[19] : |
selected_cache_line[20] ? cache_line_addr[20] : |
selected_cache_line[21] ? cache_line_addr[21] : |
selected_cache_line[22] ? cache_line_addr[22] : |
selected_cache_line[23] ? cache_line_addr[23] : |
selected_cache_line[24] ? cache_line_addr[24] : |
selected_cache_line[25] ? cache_line_addr[25] : |
selected_cache_line[26] ? cache_line_addr[26] : |
selected_cache_line[27] ? cache_line_addr[27] : |
selected_cache_line[28] ? cache_line_addr[28] : |
selected_cache_line[29] ? cache_line_addr[29] : |
selected_cache_line[30] ? cache_line_addr[30] : |
selected_cache_line[31] ? cache_line_addr[31] : |
*/ |
0; |
|
assign cache_write = wb_req & wb_we_i & wb_ack_o; |
|
assign cache_hit = |(selected_cache_line & cache_line_hit); |
|
assign cached_addr_valid = |(selected_cache_line & cache_line_addr_valid); |
|
assign wb_req_addr_hit = (wb_req & cache_hit & cached_addr_valid); |
|
// Wishbone request detection |
assign wb_req = wb_stb_i & wb_cyc_i & phy_init_done & !sync; |
|
always @(posedge wb_clk) |
wb_req_r <= wb_req; |
|
assign wb_req_new = wb_req & !wb_req_r; |
|
always @(posedge wb_clk) |
wb_req_new_r <= wb_req_new; |
|
always @(posedge wb_clk) |
if (wb_rst) |
wb_bursting <= 0; |
// Reset if acking end of transfer |
else if (wb_ack_o && wb_cti_i == 3'b111) |
wb_bursting <= 0; |
// Set if beginning new transaction and incrementing burst indicated |
// TODO - double check if this burst is going to go over a cache line |
// boundary - if so don't allow burst, fall back to classic cycles. |
else if (wb_req_new) |
wb_bursting <= (wb_cti_i == 3'b010); |
|
// Help constrain additions to appropriate bit-width for wrapping |
assign wb_burst_addr_4beat = wb_adr_i[3:2] + 1; |
assign wb_burst_addr_8beat = wb_adr_i[4:2] + 1; |
|
// Increment burst address whenever we get a hit when reading, or |
// when acking and writing. |
assign wb_burst_addr_incr = (wb_req_addr_hit & (!wb_we_i | |
(wb_we_i & wb_ack_o))); |
|
// Calculate burst address depending on burst type indicator |
always @(posedge wb_clk) |
if (wb_rst) |
wb_burst_addr <= 0; |
else if (wb_req_new) |
// When we have a bursting read to an address which is in cache then |
// initialise the address to the next word in the burst sequence. |
// If it's a miss, or it's a write, then we just take what's on the |
// bus. |
wb_burst_addr <= !(wb_req_addr_hit & !wb_we_i) ? wb_adr_i[4:2] : |
wb_bte_i==2'b01 ? {wb_adr_i[4], wb_burst_addr_4beat }: |
wb_bte_i==2'b10 ? {wb_burst_addr_8beat }: |
/*wb_bte_i==2'b11 ? wb_adr_i[5:2] + 1 :*/ |
wb_adr_i[5:2]; |
else if (wb_burst_addr_incr & wb_bte_i==2'b01) |
wb_burst_addr[1:0] <= wb_burst_addr[1:0] + 1; |
else if (wb_burst_addr_incr & wb_bte_i==2'b10) |
wb_burst_addr[2:0] <= wb_burst_addr[2:0] + 1; |
/* |
else if (wb_burst_addr_incr & wb_bte_i==2'b11) |
wb_burst_addr[3:0] <= wb_burst_addr[3:0] + 1; |
*/ |
assign ack_err = 0; |
always @(posedge wb_clk) |
ack_err_r <= 0; |
|
assign wb_err_o = 0; |
|
|
always @(posedge wb_clk) |
if (wb_rst) |
wb_ack_o <= 0; |
else |
wb_ack_o <= wb_req_addr_hit & |
( |
// Simple acks on classic cycles |
(!wb_bursting && !wb_ack_o && !wb_ack_o_r) |
// De-assert ack when we see the final transaction |
|| (wb_bursting && !(wb_cti_i==3'b111)) |
); |
|
always @(posedge wb_clk) |
wb_ack_o_r <= wb_ack_o; |
|
// Logic controling synchronisation |
always @(posedge wb_clk) |
if (wb_rst) |
sync <= 0; |
else if (sync_done) // Sync. done indicator from cache controller |
sync <= 0; |
|
always @(posedge wb_clk) |
sync_r <= sync; |
|
assign sync_start = sync & !sync_r; |
|
task do_sync; |
begin |
// Wait for us to not be doing a transaction. |
while(wb_req) |
@wb_clk; |
// Cache not busy, initiate sync. |
sync = 1; |
end |
endtask // do_sync |
|
// Wishbone side of cache enable. Always enabled unless doing DDR2-side |
// things (fill or writeback). |
assign wb_cache_en = !(do_readfrom | do_writeback); |
|
// Writeback detect logic |
always @(posedge wb_clk) |
if (wb_rst) |
do_writeback <= 0; |
else if (wb_writeback_done) |
do_writeback <= 0; |
else if (start_writeback) |
do_writeback <= 1; |
|
// DDR2 Read detect logic |
always @(posedge wb_clk) |
if (wb_rst) |
do_readfrom <= 0; |
else if (wb_readfrom_done) |
do_readfrom <= 0; |
else if (start_fill) |
do_readfrom <= 1; |
|
// Domain cross of WB control signals |
always @(negedge ddr2_if_clk) begin |
do_writeback_ddr2_sync <= do_writeback; |
do_writeback_ddr2_sync2 <= do_writeback_ddr2_sync; |
do_writeback_ddr2_sync3 <= do_writeback_ddr2_sync2; |
do_readfrom_ddr2_sync <= do_readfrom; |
do_readfrom_ddr2_sync2 <= do_readfrom_ddr2_sync; |
do_readfrom_ddr2_sync3 <= do_readfrom_ddr2_sync2; |
end |
|
assign do_readfrom_start_ddr2 = !do_readfrom_ddr2_sync3 & |
do_readfrom_ddr2_sync2; |
|
assign do_writeback_start_ddr2 = !do_writeback_ddr2_sync3 & |
do_writeback_ddr2_sync2; |
|
always @(negedge ddr2_if_clk) |
if (ddr2_rst) |
ddr2_readfrom_done <= 0; |
else if (ddr2_readfrom_done_wb_sync2) |
ddr2_readfrom_done <= 0; |
else if (ddr2_read_state_shr[6]) |
ddr2_readfrom_done <= 1; |
|
// Get readfrom_done into Wishbone domain |
always @(posedge wb_clk) |
if (wb_rst) begin |
wb_readfrom_done_sync <= 0; |
wb_readfrom_done_sync2 <= 0; |
end |
else begin |
wb_readfrom_done_sync <= ddr2_readfrom_done; |
wb_readfrom_done_sync2 <= wb_readfrom_done_sync; |
end |
|
assign wb_readfrom_done = !wb_readfrom_done_sync2 & wb_readfrom_done_sync; |
|
// Read this back to DDR2 domain |
always @(negedge ddr2_if_clk) |
if (ddr2_rst) begin |
ddr2_readfrom_done_wb_sync <= 0; |
ddr2_readfrom_done_wb_sync2 <= 0; |
end |
else begin |
ddr2_readfrom_done_wb_sync <= wb_readfrom_done_sync2; |
ddr2_readfrom_done_wb_sync2 <= ddr2_readfrom_done_wb_sync; |
end |
|
|
// Writeback finished/done logic |
always @(negedge ddr2_if_clk) |
if (ddr2_rst) |
ddr2_writeback_done <= 0; |
else if (ddr2_writeback_done_wb_sync2) |
ddr2_writeback_done <= 0; |
else if (ddr2_write_state_shr[6]) |
ddr2_writeback_done <= 1; |
|
// Get writeback_done into Wishbone domain |
always @(posedge wb_clk) |
if (wb_rst) begin |
wb_writeback_done_sync <= 0; |
wb_writeback_done_sync2 <= 0; |
end |
else begin |
wb_writeback_done_sync <= ddr2_writeback_done; |
wb_writeback_done_sync2 <= wb_writeback_done_sync; |
end |
|
assign wb_writeback_done = !wb_writeback_done_sync2 & wb_writeback_done_sync; |
|
// Read this back to DDR2 domain |
always @(negedge ddr2_if_clk) |
if (ddr2_rst) begin |
ddr2_writeback_done_wb_sync <= 0; |
ddr2_writeback_done_wb_sync2 <= 0; |
end |
else begin |
ddr2_writeback_done_wb_sync <= wb_writeback_done_sync2; |
ddr2_writeback_done_wb_sync2 <= ddr2_writeback_done_wb_sync; |
end |
|
|
// Have we passed init command to the controller? |
always @(negedge ddr2_if_clk or posedge ddr2_rst_180) |
if (ddr2_rst_180) |
ddr2_if_init_sent <= 0; |
else if (!ddr2_rst & !ddr2_rst_90 & !ddr2_rst_180 & !ddr2_if_init_sent) |
ddr2_if_init_sent <= 1; |
|
// MIG Command |
always @(negedge ddr2_if_clk or posedge ddr2_rst_180) |
if (ddr2_rst_180) |
ddr2_if_cmd <= 3'b000; |
else if (!phy_init_done) begin |
if (!ddr2_rst & !ddr2_rst_90 & !ddr2_rst_180 & !ddr2_if_init_sent) |
ddr2_if_cmd <= 3'b010; // Init |
else |
ddr2_if_cmd <= 3'b000; // NOP |
end |
else if ((ddr2_if_cmd==3'b000) & do_writeback_ddr2_sync2 & |
!ddr2_if_cmd_ack & !(|ddr2_write_state_shr[9:1]) & !ddr2_writeback_done) |
ddr2_if_cmd <= 3'b100; // Write |
else if (ddr2_write_state_shr[6]) // End of write |
ddr2_if_cmd <= 3'b000; // NOP |
else if ((ddr2_if_cmd==3'b000) & do_readfrom_ddr2_sync2 & |
!ddr2_if_cmd_ack & !(|ddr2_read_state_shr[6:1]) & !ddr2_readfrom_done) |
ddr2_if_cmd <= 3'b110; // Read |
else if (ddr2_read_state_shr[3]) |
ddr2_if_cmd <= 3'b000; // NOP |
|
// State shift register |
// [0] - Waiting for ddr2_if_cmd_ack |
// [4:1] - data0-data3 out from RAM |
// [8:5] - ddr2_if_burst_done high for 4 cycles |
// [9] - waiting for ddr2_if_cmd_ack to be deasserted |
always @(negedge ddr2_if_clk or posedge ddr2_rst_180) |
if (ddr2_rst_180) |
ddr2_write_state_shr <= 0; |
else if (!(|ddr2_write_state_shr) & !ddr2_if_cmd_ack & |
do_writeback_start_ddr2 & !ddr2_writeback_done ) |
ddr2_write_state_shr <= 1; |
else if (((|ddr2_write_state_shr[8:0]) & ddr2_if_cmd_ack) | |
(ddr2_write_state_shr[9] & !ddr2_if_cmd_ack)) |
ddr2_write_state_shr <= {ddr2_write_state_shr[8:0],1'b0}; |
|
// [0] - waiting for ddr2_if_cmd_ack |
// [4:1] - asserting ddr2_if_burst_done |
// [5] - waiting for ddr2_if_cmd_ack to be deasserted |
// [6] - finish |
always @(negedge ddr2_if_clk or posedge ddr2_rst_180) |
if (ddr2_rst_180) |
ddr2_read_state_shr <= 0; |
else if (!(|ddr2_read_state_shr) & do_readfrom_ddr2_sync2 & |
!ddr2_if_cmd_ack & !ddr2_readfrom_done) |
ddr2_read_state_shr <= 1; // Start read |
else if ((ddr2_read_state_shr[0] & ddr2_if_cmd_ack) | |
(|ddr2_read_state_shr[4:1]) | ddr2_read_state_shr[6] | |
(ddr2_read_state_shr[5] & !ddr2_if_cmd_ack & !(|ddr2_read_dv_counter_shr))) |
ddr2_read_state_shr <= {ddr2_read_state_shr[6:0],1'b0}; |
|
always @(posedge ddr2_if_clk_90 or posedge ddr2_rst_90) |
if (ddr2_rst_90) |
ddr2_read_dv_counter_shr <= 0; |
else if (do_readfrom_start_ddr2) |
ddr2_read_dv_counter_shr <= 1; |
else if (ddr2_read_dv_counter_shr[4] & !ddr2_if_cmd_ack) |
ddr2_read_dv_counter_shr <= 0; |
else if (ddr2_if_rdata_valid) |
ddr2_read_dv_counter_shr <= {ddr2_read_dv_counter_shr[3:0],1'b0}; |
|
|
assign ddr2_cache_line_word_addr_next = ddr2_cache_line_word_addr_r + 1; |
|
always @(posedge ddr2_if_clk_90 or posedge ddr2_rst_90) |
if (ddr2_rst_90) |
ddr2_cache_line_word_addr_r <= 0; |
else if (do_writeback_ddr2_sync2) begin |
// Write |
if (do_writeback_start_ddr2) |
ddr2_cache_line_word_addr_r <= 0; |
else if (ddr2_write_state_shr[4:1]) |
ddr2_cache_line_word_addr_r <= ddr2_cache_line_word_addr_next; |
end |
else if (do_readfrom_ddr2_sync2) begin |
// Read |
if (do_readfrom_start_ddr2) |
ddr2_cache_line_word_addr_r <= 0; |
else if (ddr2_if_rdata_valid) |
ddr2_cache_line_word_addr_r <= ddr2_cache_line_word_addr_next; |
end |
|
always @(posedge ddr2_if_clk_90 or posedge ddr2_rst_90) |
if (ddr2_rst_90) |
ddr2_cache_line_word_use_next_addr <= 0; |
else |
ddr2_cache_line_word_use_next_addr <= ((|ddr2_write_state_shr) & ddr2_if_cmd_ack); |
|
// Cache line word address to DDR2-side of cache. When writing, need address earlier, |
// so use the combinatorial value, otherwise the registered value. |
assign ddr2_cache_line_word_addr = ddr2_cache_line_word_use_next_addr ? |
ddr2_cache_line_word_addr_next : |
ddr2_cache_line_word_addr_r; |
|
|
assign ddr2_if_burst_done = (|ddr2_write_state_shr[7:4]) | |
(|ddr2_read_state_shr[4:1]); |
|
// Lower word address uses potentially bursting address counter |
assign wb_cache_word = wb_bursting ? |
wb_burst_addr : |
wb_adr_i[(`DDR2_CACHE_ADDR_WIDTH_WORDS_PER_LINE+2)-1:2]; |
/* |
Here `DDR2_CACHE_ADDR_WIDTH_WORDS_PER_LINE==3, which is < width of wb_burst_addr |
so just use wb_burst_addr. |
If cache lines get longer, would have to do something like this. |
{wb_adr_i[(`DDR2_CACHE_ADDR_WIDTH_WORDS_PER_LINE+2)-1:6],wb_burst_addr}: |
wb_adr_i[(`DDR2_CACHE_ADDR_WIDTH_WORDS_PER_LINE+2)-1:2]; |
*/ |
|
assign wb_cache_sel_we = {4{wb_we_i & wb_ack_o}} & wb_sel_i; |
assign ddr2_cache_en = (ddr2_if_rdata_valid |do_writeback_ddr2_sync3); |
assign ddr2_cache_we = {8{ddr2_if_rdata_valid}}; |
|
always @(negedge ddr2_if_clk) |
selected_cache_line_enc_ddr2_if_clk <= selected_cache_line_enc; |
|
always @(negedge ddr2_if_clk) |
if (do_writeback_start_ddr2) |
ddr2_if_input_address <= {cache_line_tag,3'd0}; |
else if (do_readfrom_start_ddr2) |
ddr2_if_input_address <= {wb_adr_i[`DDR2_CACHE_TAG_BITS],3'd0}; |
|
|
|
// True dual port ram, with dual aspect ration |
// Wishbone side - 32-bit, DDR2 side - 64-bit |
// Is 4KByte, so WB addr is 10-bits, DDR2 9-bits |
s3adsp_ddr2_cache s3adsp_ddr2_cache |
( |
// A-side - Wishbone |
.clka(wb_clk), |
.ena(wb_cache_en), |
.wea(({4{wb_cache_en}}&wb_cache_sel_we)), |
.addra({5'd0,selected_cache_line_enc,wb_cache_word}), |
.dina(wb_dat_i), |
.douta(wb_dat_o), |
|
// B-side - DDR2 |
.clkb(ddr2_if_clk_90), |
.enb(ddr2_cache_en), |
.web(ddr2_cache_we), |
.addrb({5'd0,selected_cache_line_enc_ddr2_if_clk,ddr2_cache_line_word_addr}), |
.dinb(ddr2_if_rdata), |
.doutb(ddr2_if_wdata) |
); |
|
s3adsp_ddr2 s3adsp_ddr2 |
( |
.cntrl0_ddr2_dq(ddr2_dq), |
.cntrl0_ddr2_a(ddr2_a), |
.cntrl0_ddr2_ba(ddr2_ba), |
.cntrl0_ddr2_cke(ddr2_cke), |
.cntrl0_ddr2_cs_n(ddr2_cs_n), |
.cntrl0_ddr2_ras_n(ddr2_ras_n), |
.cntrl0_ddr2_cas_n(ddr2_cas_n), |
.cntrl0_ddr2_we_n(ddr2_we_n), |
.cntrl0_ddr2_odt(ddr2_odt), |
.cntrl0_ddr2_dm(ddr2_dm), |
.cntrl0_rst_dqs_div_in(ddr2_rst_dqs_div_in), |
.cntrl0_rst_dqs_div_out(ddr2_rst_dqs_div_out), |
.sys_clk_in(clk133_i), |
.reset_in_n(~wb_rst), |
|
.cntrl0_burst_done(ddr2_if_burst_done), |
.cntrl0_init_done(phy_init_done), |
.cntrl0_ar_done(ddr2_if_af_done), |
.cntrl0_user_data_valid(ddr2_if_rdata_valid), |
|
.cntrl0_auto_ref_req(ddr2_if_ref_req), |
.cntrl0_user_cmd_ack(ddr2_if_cmd_ack), |
.cntrl0_user_command_register(ddr2_if_cmd), |
|
.cntrl0_clk_tb(ddr2_if_clk), |
.cntrl0_clk90_tb(ddr2_if_clk_90), |
|
.cntrl0_sys_rst_tb(ddr2_rst), |
.cntrl0_sys_rst90_tb(ddr2_rst_90), |
.cntrl0_sys_rst180_tb(ddr2_rst_180), |
|
.cntrl0_user_data_mask(8'h00), |
.cntrl0_user_output_data(ddr2_if_rdata), |
.cntrl0_user_input_data(ddr2_if_wdata), |
.cntrl0_user_input_address({ddr2_if_input_address[22:0], |
ddr2_if_input_address[24:23]}), |
.cntrl0_ddr2_dqs(ddr2_dqs), |
.cntrl0_ddr2_dqs_n(ddr2_dqs_n), |
.cntrl0_ddr2_ck(ddr2_ck), |
.cntrl0_ddr2_ck_n(ddr2_ck_n) |
); |
|
endmodule // xilinx_s3adsp_ddr2_if2 |
|
|
// Local Variables: |
// verilog-library-directories:("." "ddr2_mig") |
// verilog-library-extensions:(".v" ".h") |
// End: |
|
|
module ddr2_wb_if_cache_addr_reg |
(addr_i, validate, invalidate, |
cached_addr_o, cache_hit, addr_valid, |
clk, rst); |
|
parameter full_addr_width = 32; |
parameter word_addr_width = 2; // 4 bytes per word |
parameter line_addr_width = 5; // 32 words per "line" |
|
parameter tag_width = full_addr_width - line_addr_width - word_addr_width; |
|
|
input [full_addr_width-1: word_addr_width + line_addr_width] addr_i; |
input validate; |
input invalidate; |
output [full_addr_width-1: word_addr_width + line_addr_width] cached_addr_o; |
output cache_hit; |
output reg addr_valid; |
|
input clk, rst; |
|
reg [tag_width-1:0] cached_adr; |
|
assign cached_addr_o = cached_adr; |
|
always @(posedge clk) |
if (rst) |
cached_adr <= 0; |
else if (validate) |
cached_adr <= addr_i; |
|
always @(posedge clk) |
if (rst) |
addr_valid <= 0; |
else if (validate) |
addr_valid <= 1; |
else if (invalidate) |
addr_valid <= 0; |
|
assign cache_hit = (addr_i == cached_adr); |
|
endmodule // ddr2_wb_if_cache_addr_reg |
|
module ddr2_wb_if_cache_control |
( cache_line_addr_valid, cache_line_addr_hit, |
wb_req, |
cache_write, |
writeback_done, fill_done, |
sync_start, sync_done, |
start_writeback, start_fill, |
cache_line_validate, cache_line_invalidate, |
selected_cache_line, selected_cache_line_enc, |
wb_clk, wb_rst); |
|
parameter num_lines = 4; |
parameter num_lines_log2 = 2; |
|
input [num_lines-1:0] cache_line_addr_valid; |
input [num_lines-1:0] cache_line_addr_hit; |
|
input wb_req; |
input cache_write; |
input writeback_done, fill_done; |
|
input sync_start; |
output sync_done; |
|
output reg start_writeback; |
output reg start_fill; |
output reg [num_lines-1:0] cache_line_validate; |
output reg [num_lines-1:0] cache_line_invalidate; |
|
output [num_lines-1:0] selected_cache_line; |
output reg [num_lines_log2-1:0] selected_cache_line_enc; |
|
input wb_clk, wb_rst; |
|
reg [num_lines-1:0] lines_dirty; |
|
reg [num_lines-1:0] selected_cache_line_from_miss; |
|
reg selected_cache_line_new; |
|
reg invalidate_clean_line; |
|
reg [num_lines-1:0] selected_cache_line_r; |
reg [num_lines-1:0] selected_cache_line_r2; |
|
reg wb_req_r; |
|
wire wb_req_new; |
reg wb_req_new_r; |
|
parameter sync_line_check_wait = 4; |
reg [num_lines-1:0] sync_line_counter; |
reg sync_doing; |
reg [sync_line_check_wait-1:0] sync_line_select_wait_counter_shr; |
reg sync_line_done; |
wire sync_writeback_line; |
|
|
always @(posedge wb_clk) |
wb_req_r <= wb_req; |
|
assign wb_req_new = wb_req & !wb_req_r; |
|
always @(posedge wb_clk) |
wb_req_new_r <= wb_req_new; |
|
// Select a cache line when we miss. Currently is very simple round robin |
// TODO - if clean lines available on miss, evict them before causing a |
// writeback, to save time on cache miss. |
// TOOD - would benefit a lot from a LRU scheme. |
always @(posedge wb_clk) |
if (wb_rst) |
selected_cache_line_from_miss <= 1; |
else if (wb_req_new_r & !(|selected_cache_line_r)) // miss,no line selected |
// Shift select bit one |
selected_cache_line_from_miss |
<= {selected_cache_line_from_miss[num_lines-2:0], |
selected_cache_line_from_miss[num_lines-1]}; |
|
|
// Line selection logic, when line address is valid and hit, we select |
always @(posedge wb_clk) |
if (wb_rst) |
selected_cache_line_r <= 0; |
else if (wb_req_new) |
selected_cache_line_r <= cache_line_addr_valid & cache_line_addr_hit; |
else if (wb_req_new_r & !(|selected_cache_line_r)) |
selected_cache_line_r <= selected_cache_line_from_miss; |
else if (sync_doing) |
selected_cache_line_r <= sync_line_counter; |
|
always @(posedge wb_clk) |
selected_cache_line_r2 <= selected_cache_line_r; |
|
assign selected_cache_line = selected_cache_line_r2; |
|
// A new line of cache has been selected |
always @(posedge wb_clk) |
if (wb_rst) |
selected_cache_line_new <= 0; |
else if (wb_req_new & (&(cache_line_addr_valid & cache_line_addr_hit))) |
// New line address selected |
selected_cache_line_new <= 1; |
else if ((!selected_cache_line_new) & wb_req_new_r) |
// Didn't select one last time, so we must have forced ourselves to |
// select a new one |
selected_cache_line_new <= 1; |
else if (selected_cache_line_new) |
selected_cache_line_new <= 0; |
|
always @(posedge wb_clk) |
if (wb_rst) |
lines_dirty <= 0; |
else if (cache_write) |
lines_dirty <= lines_dirty | selected_cache_line_r; |
else if (writeback_done) |
lines_dirty <= lines_dirty & ~(selected_cache_line_r); |
|
// Validate the cache line address in the register when line filled |
always @(posedge wb_clk) |
if (wb_rst) |
cache_line_validate <= 0; |
else if (fill_done) |
cache_line_validate <= selected_cache_line_r; |
else if (|cache_line_validate) |
cache_line_validate <= 0; |
|
// Invalidate the cache line address in the register when line written back |
always @(posedge wb_clk) |
if (wb_rst) |
cache_line_invalidate <= 0; |
else if ((writeback_done & !sync_doing) | invalidate_clean_line) |
cache_line_invalidate <= selected_cache_line_r; |
else if (|cache_line_invalidate) |
cache_line_invalidate <= 0; |
|
// Initiate-writeback logic |
always @(posedge wb_clk) |
if (wb_rst) |
start_writeback <= 0; |
else if (start_writeback) |
start_writeback <= 0; |
else if (selected_cache_line_new & |
(|(lines_dirty & selected_cache_line_r)) & |
(|(selected_cache_line_r & cache_line_addr_valid)) & |
!(|(cache_line_addr_hit & selected_cache_line_r))) |
start_writeback <= 1; |
else if (sync_writeback_line) |
start_writeback <= 1; |
|
// Invalidate lines which we haven't written to so we can fill them |
always @(posedge wb_clk) |
if (wb_rst) |
invalidate_clean_line <= 0; |
else if (invalidate_clean_line) |
invalidate_clean_line <= 0; |
else if ((selected_cache_line_new) & // New line selected |
!(|(lines_dirty & selected_cache_line_r)) & // It's not dirty |
// It's valid, but we've selected it so we're trashing it |
(|(selected_cache_line_r & cache_line_addr_valid)) & |
!(|(cache_line_addr_hit & selected_cache_line_r))) // Not a hit |
invalidate_clean_line <= 1; |
|
reg invalidate_clean_line_r; |
always @(posedge wb_clk) |
invalidate_clean_line_r <= invalidate_clean_line; |
|
|
// Initiate-fill logic |
always @(posedge wb_clk) |
if (wb_rst) |
start_fill <= 0; |
else if (((selected_cache_line_new) & // New line selected |
// not valid |
!(|(cache_line_addr_valid & selected_cache_line_r))) | |
(writeback_done & !sync_doing) | invalidate_clean_line_r |
) |
start_fill <= 1; |
else if (start_fill) |
start_fill <= 0; |
|
// Hardcoded to 4 lines currently. |
always @(posedge wb_clk) |
if (selected_cache_line_r[0]) |
selected_cache_line_enc <= 0; |
else if (selected_cache_line_r[1]) |
selected_cache_line_enc <= 1; |
else if (selected_cache_line_r[2]) |
selected_cache_line_enc <= 2; |
else if (selected_cache_line_r[3]) |
selected_cache_line_enc <= 3; |
/* |
else if (selected_cache_line_r[4]) |
selected_cache_line_enc <= 4; |
else if (selected_cache_line_r[5]) |
selected_cache_line_enc <= 5; |
else if (selected_cache_line_r[6]) |
selected_cache_line_enc <= 6; |
else if (selected_cache_line_r[7]) |
selected_cache_line_enc <= 7; |
else if (selected_cache_line_r[8]) |
selected_cache_line_enc <= 8; |
else if (selected_cache_line_r[9]) |
selected_cache_line_enc <= 9; |
else if (selected_cache_line_r[10]) |
selected_cache_line_enc <= 10; |
else if (selected_cache_line_r[11]) |
selected_cache_line_enc <= 11; |
else if (selected_cache_line_r[12]) |
selected_cache_line_enc <= 12; |
else if (selected_cache_line_r[13]) |
selected_cache_line_enc <= 13; |
else if (selected_cache_line_r[14]) |
selected_cache_line_enc <= 14; |
else if (selected_cache_line_r[15]) |
selected_cache_line_enc <= 15; |
else if (selected_cache_line_r[16]) |
selected_cache_line_enc <= 16; |
else if (selected_cache_line_r[17]) |
selected_cache_line_enc <= 17; |
else if (selected_cache_line_r[18]) |
selected_cache_line_enc <= 18; |
else if (selected_cache_line_r[19]) |
selected_cache_line_enc <= 19; |
else if (selected_cache_line_r[20]) |
selected_cache_line_enc <= 20; |
else if (selected_cache_line_r[21]) |
selected_cache_line_enc <= 21; |
else if (selected_cache_line_r[22]) |
selected_cache_line_enc <= 22; |
else if (selected_cache_line_r[23]) |
selected_cache_line_enc <= 23; |
else if (selected_cache_line_r[24]) |
selected_cache_line_enc <= 24; |
else if (selected_cache_line_r[25]) |
selected_cache_line_enc <= 25; |
else if (selected_cache_line_r[26]) |
selected_cache_line_enc <= 26; |
else if (selected_cache_line_r[27]) |
selected_cache_line_enc <= 27; |
else if (selected_cache_line_r[28]) |
selected_cache_line_enc <= 28; |
else if (selected_cache_line_r[29]) |
selected_cache_line_enc <= 29; |
else if (selected_cache_line_r[30]) |
selected_cache_line_enc <= 30; |
else if (selected_cache_line_r[31]) |
selected_cache_line_enc <= 31; |
*/ |
// Synchronisation control |
|
always @(posedge wb_clk) |
if (wb_rst) |
sync_doing <= 0; |
else if (sync_start) |
sync_doing <= 1; |
else if (sync_done) |
sync_doing <= 0; |
|
always @(posedge wb_clk) |
if (wb_rst) |
sync_line_counter <= 0; |
else if (sync_start) |
// Set first line to check |
sync_line_counter[0] <= 1'b1; |
else if (sync_line_done) |
// Shift along, check next line |
sync_line_counter <= {sync_line_counter[num_lines-2:0], 1'b0}; |
|
// Pulse this on finishing of checking lines |
assign sync_done = sync_line_counter[num_lines-1] & sync_line_done; |
|
// Pulses when a dirty line is detected and should be written back. |
assign sync_writeback_line = sync_doing & |
sync_line_select_wait_counter_shr[0] & |
cache_line_addr_valid & |
|(sync_line_counter & lines_dirty); |
|
always @(posedge wb_clk) |
if (wb_rst) |
sync_line_select_wait_counter_shr <= 0; |
else if (|sync_line_select_wait_counter_shr) |
sync_line_select_wait_counter_shr |
<= {1'b0,sync_line_select_wait_counter_shr[sync_line_check_wait-1:1]}; |
else if (sync_start | (sync_line_done & !sync_done)) |
sync_line_select_wait_counter_shr[sync_line_check_wait-1] <= 1'b1; |
|
always @(posedge wb_clk) |
if (wb_rst) |
sync_line_done <= 1'b0; |
else if (sync_line_done) |
sync_line_done <= 1'b0; |
// Either line doesn't need writeback |
else if (sync_line_select_wait_counter_shr[0] & !sync_writeback_line) |
sync_line_done <= 1'b1; |
// Or writeback finished |
else if (writeback_done & sync_doing) |
sync_line_done <= 1'b1; |
|
|
endmodule // ddr2_wb_if_cache_control |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_ram8d_0.v
0,0 → 1,211
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_ram8d_0.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:42 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This module instantiates RAM16X1 premitives. There will be |
// 8 or 4 RAM16X1 instances depending on the number of data bits |
// per strobe. |
//***************************************************************************** |
|
`timescale 1ns/100ps |
`include "s3adsp_ddr2_parameters_0.v" |
module s3adsp_ddr2_ram8d_0 |
( |
output [(`DATABITSPERSTROBE -1):0] dout, |
input [3:0] waddr, |
input [(`DATABITSPERSTROBE -1):0] din, |
input [3:0] raddr, |
input wclk0, |
input wclk1, |
input we |
); |
|
|
RAM16X1D fifo_bit0 |
( |
.DPO (dout[0]), |
.A0(waddr[0]), |
.A1(waddr[1]), |
.A2(waddr[2]), |
.A3(waddr[3]), |
.D(din[0]), |
.DPRA0(raddr[0]), |
.DPRA1(raddr[1]), |
.DPRA2(raddr[2]), |
.DPRA3(raddr[3]), |
.SPO(), |
.WCLK(wclk1), |
.WE(we) |
); |
|
RAM16X1D fifo_bit1 |
( |
.DPO (dout[1]), |
.A0(waddr[0]), |
.A1(waddr[1]), |
.A2(waddr[2]), |
.A3(waddr[3]), |
.D(din[1]), |
.DPRA0(raddr[0]), |
.DPRA1(raddr[1]), |
.DPRA2(raddr[2]), |
.DPRA3(raddr[3]), |
.SPO(), |
.WCLK(wclk0), |
.WE(we) |
); |
|
|
RAM16X1D fifo_bit2 |
( |
.DPO (dout[2]), |
.A0(waddr[0]), |
.A1(waddr[1]), |
.A2(waddr[2]), |
.A3(waddr[3]), |
.D(din[2]), |
.DPRA0(raddr[0]), |
.DPRA1(raddr[1]), |
.DPRA2(raddr[2]), |
.DPRA3(raddr[3]), |
.SPO(), |
.WCLK(wclk1), |
.WE(we) |
); |
|
RAM16X1D fifo_bit3 |
( |
.DPO (dout[3]), |
.A0(waddr[0]), |
.A1(waddr[1]), |
.A2(waddr[2]), |
.A3(waddr[3]), |
.D(din[3]), |
.DPRA0(raddr[0]), |
.DPRA1(raddr[1]), |
.DPRA2(raddr[2]), |
.DPRA3(raddr[3]), |
.SPO(), |
.WCLK(wclk0), |
.WE(we) |
); |
|
RAM16X1D fifo_bit4 |
( |
.DPO (dout[4]), |
.A0(waddr[0]), |
.A1(waddr[1]), |
.A2(waddr[2]), |
.A3(waddr[3]), |
.D(din[4]), |
.DPRA0(raddr[0]), |
.DPRA1(raddr[1]), |
.DPRA2(raddr[2]), |
.DPRA3(raddr[3]), |
.SPO(), |
.WCLK(wclk1), |
.WE(we) |
); |
|
RAM16X1D fifo_bit5 |
( |
.DPO (dout[5]), |
.A0(waddr[0]), |
.A1(waddr[1]), |
.A2(waddr[2]), |
.A3(waddr[3]), |
.D(din[5]), |
.DPRA0(raddr[0]), |
.DPRA1(raddr[1]), |
.DPRA2(raddr[2]), |
.DPRA3(raddr[3]), |
.SPO(), |
.WCLK(wclk0), |
.WE(we) |
); |
|
RAM16X1D fifo_bit6 |
( |
.DPO (dout[6]), |
.A0(waddr[0]), |
.A1(waddr[1]), |
.A2(waddr[2]), |
.A3(waddr[3]), |
.D(din[6]), |
.DPRA0(raddr[0]), |
.DPRA1(raddr[1]), |
.DPRA2(raddr[2]), |
.DPRA3(raddr[3]), |
.SPO(), |
.WCLK(wclk1), |
.WE(we) |
); |
|
RAM16X1D fifo_bit7 |
( |
.DPO (dout[7]), |
.A0(waddr[0]), |
.A1(waddr[1]), |
.A2(waddr[2]), |
.A3(waddr[3]), |
.D(din[7]), |
.DPRA0(raddr[0]), |
.DPRA1(raddr[1]), |
.DPRA2(raddr[2]), |
.DPRA3(raddr[3]), |
.SPO(), |
.WCLK(wclk0), |
.WE(we) |
); |
|
|
|
|
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_tap_dly.v
0,0 → 1,521
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_tap_dly.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:42 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : Internal dqs delay structure for ddr sdram controller |
//***************************************************************************** |
|
`timescale 1ns/100ps |
module s3adsp_ddr2_tap_dly |
( |
input clk, |
input reset, |
input tapin, |
output [31:0] flop2 |
); |
|
wire [31:0] tap/* synthesis syn_keep=1 */; |
wire [31:0] flop1/* synthesis syn_keep=1 */; |
wire high; |
reg reset_r; |
|
always @( posedge clk ) |
reset_r <= reset; |
|
assign high = 1'b1; |
|
|
LUT4 # |
( |
.INIT (16'h0080) |
) |
l0 |
( |
.I0(high), |
.I1(high), |
.I2(high), |
.I3(tapin), |
.O(tap[0]) |
); |
|
LUT4 # |
( |
.INIT (16'h4000) |
) |
l1 |
( |
.I0(tap[0]), |
.I1(high), |
.I2(high), |
.I3(high), |
.O(tap[1]) |
); |
|
LUT4 # |
( |
.INIT (16'h0080) |
) |
l2 |
( |
.I0(high), |
.I1(high), |
.I2(high), |
.I3(tap[1]), |
.O(tap[2]) |
); |
|
LUT4 # |
( |
.INIT (16'h0800) |
) |
l3 |
( |
.I0(high), |
.I1(high), |
.I2(tap[2]), |
.I3(high), |
.O(tap[3]) |
); |
|
LUT4 # |
( |
.INIT (16'h0080) |
) |
l4 |
( .I0(high), |
.I1(high), |
.I2(high), |
.I3(tap[3]), |
.O(tap[4]) |
); |
|
LUT4 # |
( |
.INIT (16'h0800) |
) |
l5 |
( |
.I0(high), |
.I1(high), |
.I2(tap[4]), |
.I3(high), |
.O(tap[5]) |
); |
|
LUT4 # |
( |
.INIT (16'h0080) |
) |
l6 |
( |
.I0(high), |
.I1(high), |
.I2(high), |
.I3(tap[5]), |
.O(tap[6]) |
); |
|
LUT4 # |
( |
.INIT (16'h4000) |
) |
l7 |
( |
.I0(tap[6]), |
.I1(high), |
.I2(high), |
.I3(high), |
.O(tap[7]) |
); |
|
LUT4 # |
( |
.INIT (16'h0080) |
) |
l8 |
( |
.I0(high), |
.I1(high), |
.I2(high), |
.I3(tap[7]), |
.O(tap[8]) |
); |
|
LUT4 # |
( |
.INIT (16'h4000) |
) |
l9 |
( |
.I0(tap[8]), |
.I1(high), |
.I2(high), |
.I3(high), |
.O(tap[9]) |
); |
|
LUT4 # |
( |
.INIT (16'h0080) |
) |
l10 |
( |
.I0(high), |
.I1(high), |
.I2(high), |
.I3(tap[9]), |
.O(tap[10]) |
); |
|
LUT4 # |
( |
.INIT (16'h0800) |
) |
l11 |
( |
.I0(high), |
.I1(high), |
.I2(tap[10]), |
.I3(high), |
.O(tap[11]) |
); |
|
LUT4 # |
( |
.INIT (16'h0080) |
) |
l12 |
( |
.I0(high), |
.I1(high), |
.I2(high), |
.I3(tap[11]), |
.O(tap[12]) |
); |
|
LUT4 # |
( |
.INIT (16'h0800) |
) |
l13 |
( |
.I0(high), |
.I1(high), |
.I2(tap[12]), |
.I3(high), |
.O(tap[13]) |
); |
|
LUT4 # |
( |
.INIT (16'h0080) |
) |
l14 |
( |
.I0(high), |
.I1(high), |
.I2(high), |
.I3(tap[13]), |
.O(tap[14]) |
); |
|
LUT4 # |
( |
.INIT (16'h4000) |
) |
l15 |
( |
.I0(tap[14]), |
.I1(high), |
.I2(high), |
.I3(high), |
.O(tap[15]) |
); |
|
LUT4 # |
( |
.INIT (16'h0080) |
) |
l16 |
( |
.I0(high), |
.I1(high), |
.I2(high), |
.I3(tap[15]), |
.O(tap[16]) |
); |
|
LUT4 # |
( |
.INIT (16'h0800) |
) |
l17 |
( |
.I0(high), |
.I1(high), |
.I2(tap[16]), |
.I3(high), |
.O(tap[17]) |
); |
|
LUT4 # |
( |
.INIT (16'h0080) |
) |
l18 |
( |
.I0(high), |
.I1(high), |
.I2(high), |
.I3(tap[17]), |
.O(tap[18]) |
); |
|
LUT4 # |
( |
.INIT (16'h0800) |
) |
l19 |
( |
.I0(high), |
.I1(high), |
.I2(tap[18]), |
.I3(high), |
.O(tap[19]) |
); |
|
LUT4 # |
( |
.INIT (16'h0080) |
) |
l20 |
( |
.I0(high), |
.I1(high), |
.I2(high), |
.I3(tap[19]), |
.O(tap[20]) |
); |
|
LUT4 # |
( |
.INIT (16'h0080) |
) |
l21 |
( |
.I0(high), |
.I1(high), |
.I2(high), |
.I3(tap[20]), |
.O(tap[21]) |
); |
|
LUT4 # |
( |
.INIT (16'h4000) |
) |
l22 |
( |
.I0(tap[21]), |
.I1(high), |
.I2(high), |
.I3(high), |
.O(tap[22]) |
); |
|
LUT4 # |
( |
.INIT (16'h0080) |
) |
l23 |
( |
.I0(high), |
.I1(high), |
.I2(high), |
.I3(tap[22]), |
.O(tap[23]) |
); |
|
LUT4 # |
( |
.INIT (16'h0800) |
) |
l24 |
( |
.I0(high), |
.I1(high), |
.I2(tap[23]), |
.I3(high), |
.O(tap[24]) |
); |
|
LUT4 # |
( |
.INIT (16'h0080) |
) |
l25 |
( |
.I0(high), |
.I1(high), |
.I2(high), |
.I3(tap[24]), |
.O(tap[25]) |
); |
|
LUT4 # |
( |
.INIT (16'h0800) |
) |
l26 |
( |
.I0(high), |
.I1(high), |
.I2(tap[25]), |
.I3(high), |
.O(tap[26]) |
); |
|
LUT4 # |
( |
.INIT (16'h0080) |
) |
l27 |
( |
.I0(high), |
.I1(high), |
.I2(high), |
.I3(tap[26]), |
.O(tap[27]) |
); |
|
LUT4 # |
( |
.INIT (16'h4000) |
) |
l28 |
( |
.I0(tap[27]), |
.I1(high), |
.I2(high), |
.I3(high), |
.O(tap[28]) |
); |
|
LUT4 # |
( |
.INIT (16'h0080) |
) |
l29 |
( |
.I0(high), |
.I1(high), |
.I2(high), |
.I3(tap[28]), |
.O(tap[29]) |
); |
|
LUT4 # |
( |
.INIT (16'h4000) |
) |
l30 |
( |
.I0(tap[29]), |
.I1(high), |
.I2(high), |
.I3(high), |
.O(tap[30]) |
); |
|
LUT4 # |
( |
.INIT (16'h0080) |
) |
l31 |
( |
.I0(high), |
.I1(high), |
.I2(high), |
.I3(tap[30]), |
.O(tap[31]) |
); |
|
genvar tap_i; |
generate for(tap_i = 0; tap_i < 32; tap_i = tap_i + 1) begin: gen_tap1 |
FDR r |
( |
.Q (flop1[tap_i]), |
.C (clk), |
.D (tap[tap_i]), |
.R (reset_r) |
); |
end |
endgenerate |
|
genvar tap1_i; |
generate for(tap1_i = 0; tap1_i < 31; tap1_i = tap1_i + 1) begin: gen_tap2 |
FDR u |
( |
.Q (flop2[tap1_i]), |
.C (clk), |
.D (flop1[tap1_i] ~^ flop1[tap1_i + 1]), |
.R (reset_r) |
); |
end |
endgenerate |
|
FDR u31 |
( |
.Q (flop2[31]), |
.C (clk), |
.D (flop1[31]), |
.R (reset_r) |
); |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_clk_dcm.v
0,0 → 1,116
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_clk_dcm.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:41 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This module has the DCM instantiation to DDR2 SDRAM controller |
//***************************************************************************** |
|
`timescale 1ns/100ps |
module s3adsp_ddr2_clk_dcm |
( |
input input_clk, |
input rst, |
output clk, |
output clk90, |
output dcm_lock |
); |
|
localparam GND = 1'b0; |
|
wire clk0dcm; |
wire clk90dcm; |
wire clk0_buf; |
wire clk90_buf; |
wire dcm1_lock; |
|
assign clk = clk0_buf; |
assign clk90 = clk90_buf; |
assign dcm_lock = dcm1_lock; |
|
DCM # |
( |
.DLL_FREQUENCY_MODE ("LOW"), |
.DUTY_CYCLE_CORRECTION ("TRUE") |
) |
DCM_INST1 |
( |
.CLKIN (input_clk), |
.CLKFB (clk0_buf), |
.DSSEN (GND), |
.PSINCDEC (GND), |
.PSEN (GND), |
.PSCLK (GND), |
.RST (rst), |
.CLK0 (clk0dcm), |
.CLK90 (clk90dcm), |
.CLK180 (), |
.CLK270 (), |
.CLK2X (), |
.CLK2X180 (), |
.CLKDV (), |
.CLKFX (), |
.CLKFX180 (), |
.LOCKED (dcm1_lock), |
.PSDONE (), |
.STATUS () |
); |
|
|
BUFG BUFG_CLK0 |
( |
.O (clk0_buf), |
.I (clk0dcm) |
); |
BUFG BUFG_CLK90 |
( |
.O (clk90_buf), |
.I (clk90dcm) |
); |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_s3_dm_iob.v
0,0 → 1,91
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_s3_dm_iob_%controllerNo.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:42 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This module has instantiation DDR IOB output flip-flops, |
// and an output buffer for the data mask bits. |
//***************************************************************************** |
|
`timescale 1ns/100ps |
|
module s3adsp_ddr2_s3_dm_iob |
( |
input mask_falling, |
input mask_rising, |
input clk90, |
output ddr_dm |
); |
|
wire mask_o; |
wire gnd; |
wire vcc; |
|
assign gnd = 1'b0; |
assign vcc = 1'b1; |
|
// Data Mask Output during a write command |
FDDRRSE DDR2_DM0_OUT |
( |
.Q (mask_o), |
.C0 (~clk90), |
.C1 (clk90), |
.CE (vcc), |
.D0 (mask_rising), |
.D1 (mask_falling), |
.R (gnd), |
.S (gnd) |
); |
|
OBUF DM0_OBUF |
( |
.I (mask_o), |
.O (ddr_dm) |
); |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_wr_gray_cntr.v
0,0 → 1,124
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_wr_gray_cntr.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:42 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : |
//***************************************************************************** |
|
`timescale 1ns/100ps |
module s3adsp_ddr2_wr_gray_cntr |
( |
input clk, |
input reset, |
input cnt_en, |
output [3:0] wgc_gcnt |
); |
reg [3:0] d_in; |
wire [3:0] gc_int; |
|
assign wgc_gcnt = gc_int; |
always @(gc_int) begin |
case (gc_int) |
4'b0000 : d_in <= 4'b0001; //1 |
4'b0001 : d_in <= 4'b0011; //3 |
4'b0010 : d_in <= 4'b0110; //6 |
4'b0011 : d_in <= 4'b0010; //2 |
4'b0100 : d_in <= 4'b1100; //c |
4'b0101 : d_in <= 4'b0100; //4 |
4'b0110 : d_in <= 4'b0111; //7 |
4'b0111 : d_in <= 4'b0101; //5 |
4'b1000 : d_in <= 4'b0000; //0 |
4'b1001 : d_in <= 4'b1000; //8 |
4'b1010 : d_in <= 4'b1011; //b |
4'b1011 : d_in <= 4'b1001; //9 |
4'b1100 : d_in <= 4'b1101; //d |
4'b1101 : d_in <= 4'b1111; //f |
4'b1110 : d_in <= 4'b1010; //a |
4'b1111 : d_in <= 4'b1110; //e |
default : d_in <= 4'b0001; //1 |
endcase |
end |
|
FDCE bit0 |
( |
.Q(gc_int[0]), |
.C(clk), |
.CE(cnt_en), |
.CLR(reset), |
.D(d_in[0]) |
); |
|
FDCE bit1 |
( |
.Q(gc_int[1]), |
.C(clk), |
.CE(cnt_en), |
.CLR(reset), |
.D(d_in[1]) |
); |
|
FDCE bit2 |
( |
.Q(gc_int[2]), |
.C(clk), |
.CE(cnt_en), |
.CLR(reset), |
.D(d_in[2]) |
); |
|
FDCE bit3 |
( |
.Q(gc_int[3]), |
.C(clk), |
.CE(cnt_en), |
.CLR(reset), |
.D(d_in[3]) |
); |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_cal_ctl.v
0,0 → 1,192
//***************************************************************************** |
// (c) Copyright 2005 - 2009 Xilinx, Inc. All rights reserved. |
// |
// This file contains confidential and proprietary information |
// of Xilinx, Inc. and is protected under U.S. and |
// international copyright and other intellectual property |
// laws. |
// |
// DISCLAIMER |
// This disclaimer is not a license and does not grant any |
// rights to the materials distributed herewith. Except as |
// otherwise provided in a valid license issued to you by |
// Xilinx, and to the maximum extent permitted by applicable |
// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND |
// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES |
// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING |
// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- |
// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and |
// (2) Xilinx shall not be liable (whether in contract or tort, |
// including negligence, or under any other theory of |
// liability) for any loss or damage of any kind or nature |
// related to, arising under or in connection with these |
// materials, including for any direct, or any indirect, |
// special, incidental, or consequential loss or damage |
// (including loss of data, profits, goodwill, or any type of |
// loss or damage suffered as a result of any action brought |
// by a third party) even if such damage or loss was |
// reasonably foreseeable or Xilinx had been advised of the |
// possibility of the same. |
// |
// CRITICAL APPLICATIONS |
// Xilinx products are not designed or intended to be fail- |
// safe, or for use in any application requiring fail-safe |
// performance, such as life-support or safety devices or |
// systems, Class III medical devices, nuclear facilities, |
// applications related to the deployment of airbags, or any |
// other applications that could lead to death, personal |
// injury, or severe property or environmental damage |
// (individually and collectively, "Critical |
// Applications"). Customer assumes the sole risk and |
// liability of any use of Xilinx products in Critical |
// Applications, subject only to applicable laws and |
// regulations governing limitations on product liability. |
// |
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS |
// PART OF THIS FILE AT ALL TIMES. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_cal_ctl.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:41 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This module generates the select lines for the LUT delay |
// circuit that generate the required delay for the DQS with |
// respect to the DQ. It calculates the dealy of a LUT |
// dynamically by finding the number of LUTs in a clock phase. |
//***************************************************************************** |
|
`timescale 1ns/100ps |
|
module s3adsp_ddr2_cal_ctl |
( |
input clk, |
input reset, |
input [31:0] flop2, |
output reg [4:0] tapfordqs/* synthesis syn_keep=1 */, |
// debug signals |
output [4:0] dbg_phase_cnt, |
output [5:0] dbg_cnt, |
output dbg_trans_onedtct, |
output dbg_trans_twodtct, |
output dbg_enb_trans_two_dtct |
); |
|
|
localparam tap1 = 5'b01111; |
localparam tap2 = 5'b10111; |
localparam tap3 = 5'b11011; |
localparam tap4 = 5'b11101; |
localparam tap5 = 5'b11110; |
localparam tap6 = 5'b11111; |
localparam default_tap = 5'b11101; |
|
reg [5:0] cnt/* synthesis syn_preserve=1 */; |
reg [5:0] cnt1/* synthesis syn_preserve=1 */; |
reg [4:0] phase_cnt/* synthesis syn_preserve=1 */; |
reg [31:0] tap_dly_reg/* synthesis syn_preserve=1 */; |
reg [4:0] tapfordqs1/* synthesis syn_preserve=1 */; |
reg reset_r/* synthesis syn_preserve=1 */; |
reg trans_onedtct; |
reg trans_twodtct; |
reg enb_trans_two_dtct; |
|
assign dbg_phase_cnt = phase_cnt; |
assign dbg_cnt = cnt1; |
assign dbg_trans_onedtct = trans_onedtct; |
assign dbg_trans_twodtct = trans_twodtct; |
assign dbg_enb_trans_two_dtct = enb_trans_two_dtct; |
|
always @( posedge clk ) |
reset_r <= reset; |
|
always @(posedge clk) begin |
if(reset_r) |
enb_trans_two_dtct <= 1'b0; |
else if(phase_cnt >= 5'd1) |
enb_trans_two_dtct <= 1'b1; |
else |
enb_trans_two_dtct <= 1'b0; |
end |
|
always @(posedge clk) begin |
if(reset_r) |
tap_dly_reg <= 32'd0; |
else if(cnt[5] == 1'b1) |
tap_dly_reg <= flop2; |
else |
tap_dly_reg <= tap_dly_reg; |
end |
|
/*********** Free Running Counter For Counting 32 States *******************/ |
/*********** Two parallel counters are used to fix the timing **************/ |
|
always @(posedge clk) begin |
if(reset_r || (cnt[5] == 1'b1)) |
cnt[5:0] <= 6'b0; |
else |
cnt[5:0] <= cnt[5:0] + 1'b1; |
end |
|
|
always @(posedge clk) begin |
if(reset_r || (cnt1[5] == 1'b1)) |
cnt1[5:0] <= 6'b0; |
else |
cnt1[5:0] <= cnt1[5:0] + 1'b1; |
end |
|
always @(posedge clk) begin |
if(reset_r || (cnt[5] == 1'b1)) |
phase_cnt <= 5'd0; |
else if (trans_onedtct && (!trans_twodtct)) |
phase_cnt <= phase_cnt + 1; |
else |
phase_cnt <= phase_cnt; |
end |
|
/**************** Checking For The First Transition ***************************/ |
always @(posedge clk) begin |
if(reset_r || (cnt[5] == 1'b1)) begin |
trans_onedtct <= 1'b0; |
trans_twodtct <= 1'b0; |
end |
else if (cnt[4:0] == 5'd0 && tap_dly_reg[0]) begin |
trans_onedtct <= 1'b1; |
trans_twodtct <= 1'b0; |
end |
else if ((tap_dly_reg[cnt[4:0]]) && (trans_twodtct == 1'b0)) begin |
if((trans_onedtct == 1'b1) && (enb_trans_two_dtct) ) |
trans_twodtct <= 1'b1; |
else |
trans_onedtct <= 1'b1; |
end |
end |
// Tap values for Left/Right banks |
always @(posedge clk) begin |
if(reset_r) |
tapfordqs1 <= default_tap; |
else if(cnt1[4] && cnt1[3] && |
cnt1[2] && cnt1[1] && cnt1[0]) begin |
if((trans_onedtct == 1'b0) || (trans_twodtct == 1'b0) |
|| (phase_cnt > 5'd11)) |
tapfordqs1 <= tap4; |
else if((phase_cnt > 5'd8)) |
tapfordqs1 <= tap3; |
else |
tapfordqs1 <= tap2; |
end |
else |
tapfordqs1 <= tapfordqs1; |
end |
|
always @(posedge clk) |
tapfordqs <= tapfordqs1; |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_infrastructure_top.v
0,0 → 1,240
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007, 2008 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_infrastructure_top.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:41 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This module has instantiations clk_dcm and cal_top. |
// This generate reset signals. |
//***************************************************************************** |
|
`timescale 1ns/100ps |
`include "s3adsp_ddr2_parameters_0.v" |
module s3adsp_ddr2_infrastructure_top |
( |
input sys_clk, |
input sys_clkb, |
input sys_clk_in, |
input reset_in_n, |
output [4:0] delay_sel_val1_val, |
output sys_rst_val, |
output sys_rst90_val, |
output sys_rst180_val, |
output reg wait_200us_rout, |
output clk_int_val, |
output clk90_int_val, |
// debug signals |
output [4:0] dbg_phase_cnt, |
output [5:0] dbg_cnt, |
output dbg_trans_onedtct, |
output dbg_trans_twodtct, |
output dbg_enb_trans_two_dtct |
|
); |
|
wire user_rst; |
wire clk_int; |
wire clk90_int; |
wire dcm_lock; |
wire sys_clk_ibuf; |
wire clk_int_val1; |
wire clk_int_val2; |
wire clk90_int_val1; |
wire clk90_int_val2; |
wire [4:0] delay_sel_val; |
wire user_cal_rst; |
reg sys_rst_o; |
reg sys_rst_1; |
reg sys_rst; |
reg sys_rst90_o; |
reg sys_rst90_1; |
reg sys_rst90; |
reg sys_rst180_o; |
reg sys_rst180_1; |
reg sys_rst180; |
reg [15:0] counter200; |
reg wait_200us; |
reg wait_clk90; |
reg wait_clk270; |
reg wait_200us_r; |
|
generate |
if(`CLK_TYPE == "DIFFERENTIAL") begin : DIFF_ENDED_CLKS_INST |
|
IBUFGDS_LVDS_25 SYS_CLK_INST |
( |
.I (sys_clk), |
.IB (sys_clkb), |
.O (sys_clk_ibuf) |
); |
end else if(`CLK_TYPE == "SINGLE_ENDED") begin : SINGLE_ENDED_CLKS_INST |
/* |
IBUFG SYS_CLK_INST |
( |
.I (sys_clk_in), |
.O (sys_clk_ibuf) |
); |
*/ |
assign sys_clk_ibuf = sys_clk_in; |
|
end |
endgenerate |
|
assign clk_int_val = clk_int; |
assign clk90_int_val = clk90_int; |
assign sys_rst_val = sys_rst; |
assign sys_rst90_val = sys_rst90; |
assign sys_rst180_val = sys_rst180; |
assign delay_sel_val1_val = delay_sel_val; |
assign clk_int_val1 = clk_int; |
assign clk90_int_val1 = clk90_int; |
assign clk_int_val2 = clk_int_val1; |
assign clk90_int_val2 = clk90_int_val1; |
assign user_rst = `RESET_ACTIVE_LOW == 1'b1 ? |
~reset_in_n : reset_in_n; |
assign user_cal_rst = `RESET_ACTIVE_LOW == 1'b1 ? |
reset_in_n : ~reset_in_n; |
|
always @(posedge clk_int_val2) begin |
if(user_rst == 1'b1 || dcm_lock == 1'b0) begin |
wait_200us <= 1'b1; |
counter200 <= 16'd0; |
end |
else |
`ifdef simulation |
wait_200us <= 1'b0; |
`else |
if ( counter200 < 16'd33400 ) begin |
counter200 <= counter200 + 1'b1; |
wait_200us <= 1'b1; |
end |
else begin |
counter200 <= counter200; |
wait_200us <= 1'b0; |
end |
`endif |
end |
|
always @( posedge clk_int_val2 ) |
wait_200us_r <= wait_200us; |
|
always @( posedge clk_int_val2 ) |
wait_200us_rout <= wait_200us; |
|
always @(negedge clk90_int_val2) begin |
if(user_rst == 1'b1 || dcm_lock == 1'b0) |
wait_clk270 <= 1'b1; |
else |
wait_clk270 <= wait_200us_r; |
end |
|
always @(posedge clk90_int_val2) begin |
wait_clk90 <= wait_clk270; |
end |
|
always@(posedge clk_int_val2) begin |
if(user_rst == 1'b1 || dcm_lock == 1'b0 || wait_200us_r == 1'b1 ) begin |
sys_rst_o <= 1'b1; |
sys_rst_1 <= 1'b1; |
sys_rst <= 1'b1; |
end |
else begin |
sys_rst_o <= 1'b0; |
sys_rst_1 <= sys_rst_o; |
sys_rst <= sys_rst_1; |
end |
end |
|
always@(posedge clk90_int_val2) begin |
if (user_rst == 1'b1 || dcm_lock == 1'b0 || wait_clk90 == 1'b1) begin |
sys_rst90_o <= 1'b1; |
sys_rst90_1 <= 1'b1; |
sys_rst90 <= 1'b1; |
end |
else begin |
sys_rst90_o <= 1'b0; |
sys_rst90_1 <= sys_rst90_o; |
sys_rst90 <= sys_rst90_1; |
end |
end |
|
always@(negedge clk_int_val2) begin |
if (user_rst == 1'b1 || dcm_lock == 1'b0 || wait_clk270 == 1'b1) begin |
sys_rst180_o <= 1'b1; |
sys_rst180_1 <= 1'b1; |
sys_rst180 <= 1'b1; |
end |
else begin |
sys_rst180_o <= 1'b0; |
sys_rst180_1 <= sys_rst180_o; |
sys_rst180 <= sys_rst180_1; |
end |
end |
|
s3adsp_ddr2_clk_dcm clk_dcm0 |
( |
.input_clk (sys_clk_ibuf), |
.rst (user_rst), |
.clk (clk_int), |
.clk90 (clk90_int), |
.dcm_lock (dcm_lock) |
); |
|
s3adsp_ddr2_cal_top cal_top0 |
( |
.clk0 (clk_int_val2), |
.clk0dcmlock (dcm_lock), |
.reset (user_cal_rst), |
.tapfordqs (delay_sel_val), |
.dbg_phase_cnt (dbg_phase_cnt), |
.dbg_cnt (dbg_cnt), |
.dbg_trans_onedtct (dbg_trans_onedtct), |
.dbg_trans_twodtct (dbg_trans_twodtct), |
.dbg_enb_trans_two_dtct (dbg_enb_trans_two_dtct) |
); |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_s3_dq_iob.v
0,0 → 1,121
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007, 2008 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_s3_dq_iob.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:42 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This module instantiate DDR IOB output flip-flops, an |
// output buffer with registered tri-state, and an input buffer |
// for a single data/dq bit. The DDR IOB output flip-flops |
// are used to forward data to memory during a write. |
//***************************************************************************** |
|
|
`timescale 1ns/100ps |
module s3adsp_ddr2_s3_dq_iob |
( |
inout ddr_dq_inout, |
input write_data_falling, |
input write_data_rising, |
input clk90, |
input write_en_val, |
output read_data_in |
); |
|
localparam GND = 1'b0; |
localparam CLOCK_EN = 1'b1; |
|
wire ddr_en; |
wire ddr_dq_q; |
wire enable_b; |
wire write_data_rising1; |
wire write_data_falling1; |
|
assign enable_b = ~ write_en_val; |
|
// # delays are used for simulation purpose(delta delay). |
|
assign #1 write_data_rising1 = write_data_rising; |
|
assign #1 write_data_falling1 = write_data_falling; |
|
//Transmission data path |
|
FDDRRSE DDR_OUT |
( |
.Q (ddr_dq_q), |
.C0 (~clk90), |
.C1 (clk90), |
.CE (CLOCK_EN), |
.D0 (write_data_rising1), |
.D1 (write_data_falling1), |
.R (GND), |
.S (GND) |
); |
|
(* IOB = "FORCE" *) FD DQ_T |
( |
.D (enable_b), |
.C (~clk90), |
.Q (ddr_en) |
)/* synthesis syn_useioff = 1 */; |
|
OBUFT DQ_OBUFT |
( |
.I (ddr_dq_q), |
.T (ddr_en), |
.O (ddr_dq_inout) |
); |
|
//Receive data path |
|
IBUF DQ_IBUF |
( |
.I (ddr_dq_inout), |
.O (read_data_in) |
); |
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_data_write_0.v
0,0 → 1,156
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007, 2008 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : data_write.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:41 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : Data write operation performed through the pipelines in this |
// module. |
//***************************************************************************** |
|
`timescale 1ns/100ps |
`include "s3adsp_ddr2_parameters_0.v" |
|
module s3adsp_ddr2_data_write_0 |
( |
input [((`DATA_WIDTH*2)-1):0] user_input_data, |
input [((`DATA_MASK_WIDTH*2)-1):0] user_data_mask, |
input clk90, |
input write_enable, |
output reg write_en_val, |
output [((`DATA_WIDTH)-1):0] write_data_falling, |
output [((`DATA_WIDTH)-1):0] write_data_rising, |
output [((`DATA_MASK_WIDTH)-1):0] data_mask_f, |
output [((`DATA_MASK_WIDTH)-1):0] data_mask_r |
); |
|
reg write_en_P1; |
|
reg [((`DATA_WIDTH*2)-1):0] write_data1; |
reg [((`DATA_WIDTH*2)-1):0] write_data2; |
reg [((`DATA_WIDTH*2)-1):0] write_data3; |
reg [((`DATA_WIDTH*2)-1):0] write_data4 |
/* synthesis syn_srlstyle="registers" */; |
reg [((`DATA_MASK_WIDTH*2)-1):0] write_data_m1; |
reg [((`DATA_MASK_WIDTH*2)-1):0] write_data_m2; |
reg [((`DATA_MASK_WIDTH*2)-1):0] write_data_m3; |
reg [((`DATA_MASK_WIDTH*2)-1):0] write_data_m4; |
|
reg [(`DATA_WIDTH-1):0] write_data90; |
reg [(`DATA_WIDTH-1):0] write_data90_1; |
reg [(`DATA_WIDTH-1):0] write_data90_2; |
reg [(`DATA_WIDTH-1):0] write_data270; |
reg [(`DATA_WIDTH-1):0] write_data270_1; |
reg [(`DATA_WIDTH-1):0] write_data270_2; |
|
reg [(`DATA_MASK_WIDTH-1):0] write_data_m90; |
reg [(`DATA_MASK_WIDTH-1):0] write_data_m90_1; |
reg [(`DATA_MASK_WIDTH-1):0] write_data_m90_2; |
|
reg [((`DATA_MASK_WIDTH)-1):0] write_data_m270; |
reg [((`DATA_MASK_WIDTH)-1):0] write_data_m270_1; |
reg [((`DATA_MASK_WIDTH)-1):0] write_data_m270_2; |
|
wire [((`DATA_WIDTH*2)-1):0] write_data0; |
wire [((`DATA_MASK_WIDTH*2)-1):0] write_data_m0; |
|
|
assign write_data0 = user_input_data; |
assign write_data_m0 = user_data_mask; |
|
always@(posedge clk90) begin |
write_data1 <= write_data0; |
write_data2 <= write_data1; |
write_data3 <= write_data2; |
write_data4 <= write_data3; |
end |
|
always@(posedge clk90) begin |
write_data_m1 <= write_data_m0; |
write_data_m2 <= write_data_m1; |
write_data_m3 <= write_data_m2; |
write_data_m4 <= write_data_m3; |
end |
|
always@(posedge clk90) begin |
write_data90 <= write_data4[`DATA_WIDTH-1 : 0]; |
write_data_m90 <= write_data_m4[`DATA_MASK_WIDTH-1:0]; |
write_data90_1 <= write_data90; |
write_data_m90_1 <= write_data_m90; |
write_data90_2 <= write_data90_1; |
write_data_m90_2 <= write_data_m90_1; |
|
end |
|
always@ (negedge clk90) begin |
write_data270 <= write_data4[(`DATA_WIDTH*2)-1 : `DATA_WIDTH]; |
write_data_m270 <= write_data_m4[(`DATA_MASK_WIDTH*2)-1:`DATA_MASK_WIDTH]; |
|
write_data270_1 <= write_data270; |
write_data_m270_1 <= write_data_m270; |
write_data270_2 <= write_data270_1; |
write_data_m270_2 <= write_data_m270_1; |
|
end |
|
assign write_data_rising = write_data270_2; |
assign write_data_falling = write_data90_2; |
|
assign data_mask_r = write_data_m270_2; |
assign data_mask_f = write_data_m90_2; |
|
|
// write enable for data path |
always@(posedge clk90) begin |
write_en_P1 <= write_enable; |
end |
|
always@(negedge clk90) begin |
write_en_val <= write_en_P1; |
end |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_controller_0.v
0,0 → 1,1176
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007, 2008 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_controller_0.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:41 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This is main controller block. This includes the following |
// features: |
// - The controller state machine that controls the |
// initialization process upon power up, as well as the |
// read, write, and refresh commands. |
// - Accepts and decodes the user commands. |
// - Generates the address and Bank address and control signals |
// to the memory |
// - Generates control signals for other modules. |
//***************************************************************************** |
`timescale 1ns/100ps |
`include "s3adsp_ddr2_parameters_0.v" |
|
module s3adsp_ddr2_controller_0 |
( |
input clk/* synthesis syn_keep=1 */, |
input rst0, |
input rst180, |
input [((`ROW_ADDRESS |
+ `COLUMN_ADDRESS)-1):0] address, |
input [`BANK_ADDRESS-1:0] bank_address, |
input [2:0] command_register, |
input burst_done, |
output ddr_rasb_cntrl, |
output ddr_casb_cntrl, |
output [`BANK_ADDRESS-1:0] ddr_ba_cntrl, |
output [`ROW_ADDRESS-1:0] ddr_address_cntrl, |
output ddr_csb_cntrl, |
output dqs_enable, |
output dqs_reset /* synthesis syn_keep=1 */, |
output rst_dqs_div_int, |
output cmd_ack, |
output init, |
output ddr_web_cntrl, |
output ddr_cke_cntrl, |
output reg write_enable, |
output reg rst_calib, |
output reg ddr_odt_cntrl, |
output reg ar_done, |
input wait_200us, |
output auto_ref_req, |
output reg read_fifo_rden // Read Enable signal for read fifo(to data_read module) |
); |
|
localparam IDLE = 4'b0000; |
localparam PRECHARGE = 4'b0001; |
localparam AUTO_REFRESH = 4'b0010; |
localparam ACTIVE = 4'b0011; |
localparam FIRST_WRITE = 4'b0100; |
localparam WRITE_WAIT = 4'b0101; |
localparam BURST_WRITE = 4'b0110; |
localparam PRECHARGE_AFTER_WRITE = 4'b0111; |
localparam PRECHARGE_AFTER_WRITE_2 = 4'b1000; |
localparam READ_WAIT = 4'b1001; |
localparam BURST_READ = 4'b1010; |
localparam ACTIVE_WAIT = 4'b1011; |
|
localparam INIT_IDLE = 2'b00; |
localparam INIT_PRECHARGE = 2'b01; |
localparam INIT_LOAD_MODE_REG = 2'b10; |
localparam INIT_AUTO_REFRESH = 2'b11; |
|
parameter COL_WIDTH = `COLUMN_ADDRESS; |
parameter ROW_WIDTH = `ROW_ADDRESS; |
|
|
reg [3:0] current_state; |
reg [3:0] next_state; |
reg [1:0] init_current_state; |
reg [1:0] init_next_state; |
reg [((`ROW_ADDRESS |
+ `COLUMN_ADDRESS)-1):0] address_reg; |
reg auto_ref; |
reg auto_ref1; |
reg autoref_value; |
reg auto_ref_detect1; |
reg [(`MAX_REF_WIDTH-1):0] autoref_count; |
reg auto_ref_issued; |
reg [`BANK_ADDRESS-1:0] ba_address_reg1; |
reg [`BANK_ADDRESS-1:0] ba_address_reg2; |
reg [2:0] burst_length; |
reg [2:0] cas_count; |
reg [4:0] ras_count; |
|
reg [`ROW_ADDRESS-1:0] column_address_reg; |
reg [`ROW_ADDRESS-1:0] column_address_reg1; |
reg [2:0] wr; |
reg ddr_rasb2; |
reg ddr_casb2; |
reg ddr_web2; |
reg [`BANK_ADDRESS-1:0] ddr_ba1; |
reg [`ROW_ADDRESS-1:0] ddr_address1; |
reg [3:0] init_count; |
reg init_done; |
reg init_done_r1; |
reg init_memory; |
reg init_mem; |
reg [6:0] init_pre_count; |
reg [7:0] dll_rst_count; |
reg [(`MAX_REF_WIDTH-1):0] ref_freq_cnt; |
reg read_cmd1; |
reg read_cmd2; |
reg read_cmd3; |
reg [2:0] rcd_count; |
reg [7:0] rfc_counter_value; |
reg [7:0] rfc_count; |
reg rfc_count_reg; |
reg ar_done_reg; |
reg rdburst_end_1; |
reg rdburst_end_2; |
reg [`ROW_ADDRESS-1:0] row_address_reg; |
reg rst_dqs_div_r; |
reg rst_dqs_div_r1; //For Reg Dimm |
reg [2:0] wrburst_end_cnt; |
reg wrburst_end_1; |
reg wrburst_end_2; |
reg wrburst_end_3; |
reg [2:0] wr_count; |
reg write_cmd1; |
reg write_cmd2; |
reg write_cmd3; |
reg [2:0] dqs_div_cascount; |
reg [2:0] dqs_div_rdburstcount; |
reg dqs_enable1; |
reg dqs_enable2; |
reg dqs_enable3; |
reg dqs_reset1_clk0; |
reg dqs_reset2_clk0; |
reg dqs_reset3_clk0; |
reg dqs_enable_int; |
reg dqs_reset_int; |
reg rst180_r; |
reg rst0_r; |
reg ddr_odt2; |
reg go_to_active; |
reg accept_cmd_in; |
reg odt_deassert; |
reg [2:0] rp_count; |
reg auto_ref_wait; |
reg auto_ref_wait1; |
reg auto_ref_wait2; |
reg [7:0] count6; |
|
|
wire [`ROW_ADDRESS - 1:0] lmr; |
wire [`ROW_ADDRESS - 1:0] emr; |
wire [`ROW_ADDRESS - 1:0] lmr_dll_rst; |
wire [`ROW_ADDRESS - 1:0] lmr_dll_set; |
wire [`ROW_ADDRESS-1:0] column_address; |
|
wire write_cmd_in; |
wire read_cmd_in; |
wire init_cmd_in; |
wire wrburst_end; |
wire [`ROW_ADDRESS-1:0] row_address; |
wire rdburst_end; |
wire init_done_value; |
wire ddr_rasb1; |
wire ddr_casb1; |
wire ddr_web1; |
wire ack_reg; |
wire ack_o; |
wire auto_ref_issued_p; |
wire ar_done_p; |
wire go_to_active_value; |
wire ddr_odt1; |
wire rst_dqs_div_int1; |
wire [2:0] burst_cnt_max; |
|
|
// Input : COMMAND REGISTER FORMAT |
// 000 - NOP |
// 010 - Initialize memory |
// 100 - Write Request |
// 110 - Read request |
|
// Input : Address format |
// row address = address((`ROW_ADDRESS+ `COLUMN_ADDRESS) -1 : `COLUMN_ADDRESS) |
// column addres = address( `COLUMN_ADDRESS-1 : 0) |
|
assign ddr_csb_cntrl = 1'b0; |
assign row_address = address_reg[((`ROW_ADDRESS + |
`COLUMN_ADDRESS)-1): |
`COLUMN_ADDRESS]; |
assign init = init_done; |
assign ddr_rasb_cntrl = ddr_rasb2; |
assign ddr_casb_cntrl = ddr_casb2; |
assign ddr_web_cntrl = ddr_web2; |
assign ddr_address_cntrl = ddr_address1; |
assign ddr_ba_cntrl = ddr_ba1; |
assign rst_dqs_div_int = rst_dqs_div_int1; |
assign emr = `EXT_LOAD_MODE_REGISTER; |
assign lmr = `LOAD_MODE_REGISTER; |
assign lmr_dll_rst = {lmr[`ROW_ADDRESS - 1 : 9],1'b1,lmr[7:0]}; |
assign lmr_dll_set = {lmr[`ROW_ADDRESS - 1 : 9],1'b0,lmr[7:0]}; |
assign ddr_cke_cntrl = ~wait_200us; |
|
// turn off auto-precharge when issuing read/write commands (A10 = 0) |
// mapping the column address for linear addressing. |
generate |
if (COL_WIDTH == ROW_WIDTH-1) begin: gen_ddr_addr_col_0 |
assign column_address = {address_reg[COL_WIDTH-1:10], 1'b0, |
address_reg[9:0]}; |
end else begin |
if (COL_WIDTH > 10) begin: gen_ddr_addr_col_1 |
assign column_address = {{(ROW_WIDTH-COL_WIDTH-1){1'b0}}, |
address_reg[COL_WIDTH-1:10], 1'b0, |
address_reg[9:0]}; |
end else begin: gen_ddr_addr_col_2 |
assign column_address = {{(ROW_WIDTH-COL_WIDTH-1){1'b0}}, 1'b0, |
address_reg[COL_WIDTH-1:0]}; |
end |
end |
endgenerate |
|
always @ (negedge clk) |
rst180_r <= rst180; |
|
always @ (posedge clk) |
rst0_r <= rst0; |
|
//****************************************************************************** |
// Register user address |
//****************************************************************************** |
|
always @ (negedge clk) begin |
row_address_reg <= row_address; |
column_address_reg <= column_address; |
ba_address_reg1 <= bank_address; |
ba_address_reg2 <= ba_address_reg1; |
address_reg <= address; |
end |
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) begin |
burst_length <= 3'b000; |
wr <= 3'd0; |
end |
else begin |
burst_length <= lmr[2:0]; |
wr <= `TWR_COUNT_VALUE; |
end |
end |
|
always @( negedge clk ) begin |
if ( rst180_r ) |
accept_cmd_in <= 1'b0; |
else if ( current_state == IDLE && ((rp_count == 3'd0 && rfc_count_reg && |
!auto_ref_wait && !auto_ref_issued))) |
accept_cmd_in <= 1'b1; |
else |
accept_cmd_in <= 1'b0; |
end |
|
|
//****************************************************************************** |
// Commands from user. |
//****************************************************************************** |
assign init_cmd_in = (command_register == 3'b010); |
assign write_cmd_in = (command_register == 3'b100 && |
accept_cmd_in == 1'b1) ; |
assign read_cmd_in = (command_register == 3'b110 && |
accept_cmd_in == 1'b1) ; |
|
//****************************************************************************** |
// write_cmd1 is asserted when user issued write command and the controller s/m |
// is in idle state and AUTO_REF is not asserted. |
//****************************************************************************** |
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) begin |
write_cmd1 <= 1'b0; |
write_cmd2 <= 1'b0; |
write_cmd3 <= 1'b0; |
end |
else begin |
if (accept_cmd_in) |
write_cmd1 <= write_cmd_in; |
write_cmd2 <= write_cmd1; |
write_cmd3 <= write_cmd2; |
end |
end |
|
//****************************************************************************** |
// read_cmd1 is asserted when user issued read command and the controller s/m |
// is in idle state and AUTO_REF is not asserted. |
//****************************************************************************** |
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) begin |
read_cmd1 <= 1'b0; |
read_cmd2 <= 1'b0; |
read_cmd3 <= 1'b0; |
end |
else begin |
if (accept_cmd_in) |
read_cmd1 <= read_cmd_in; |
read_cmd2 <= read_cmd1; |
read_cmd3 <= read_cmd2; |
end |
end |
|
//****************************************************************************** |
// ras_count- Active to Precharge time |
// Controller is giving tras violation when user issues a single read command for |
// BL=4 and tRAS is more then 42ns.It uses a fixed clk count of 7 clocks which is |
// 7*6(@166) = 42ns. Addded ras_count counter which will take care of tras timeout. |
// RAS_COUNT_VALUE parameter is used to load the counter and it depends on the |
// selected memory and frequency |
//****************************************************************************** |
always @( negedge clk ) begin |
if ( rst180_r ) |
ras_count <= 5'd0; |
else if ( current_state == ACTIVE ) |
ras_count <= `RAS_COUNT_VALUE-1; |
else if ( ras_count != 5'b00000 ) |
ras_count <= ras_count - 1'b1; |
end |
//****************************************************************************** |
// rfc_count |
// An executable command can be issued only after Trfc period after a AUTOREFRESH |
// command is issued. rfc_count_value is set in the parameter file depending on |
// the memory device speed grade and the selected frequency.For example for 5B |
// speed grade, trfc= 75 at 133Mhz, rfc_counter_value = 8'b00001010. |
// ( Trfc/clk_period= 75/7.5= 10) |
//****************************************************************************** |
|
always @( negedge clk ) begin |
if (rst180_r == 1'b1) |
rfc_count <= 8'd0; |
else if(current_state == AUTO_REFRESH) |
rfc_count <= rfc_counter_value; |
else if(rfc_count != 8'd0) |
rfc_count <= rfc_count - 1'b1; |
end |
|
//****************************************************************************** |
// rp_count |
// An executable command can be issued only after Trp period after a PRECHARGE |
// command is issued. |
//****************************************************************************** |
|
always @( negedge clk ) begin |
if ( rst180_r ) |
rp_count <= 3'b000; |
else if ( current_state == PRECHARGE ) |
rp_count <= `RP_COUNT_VALUE; |
else if ( rp_count != 3'b000 ) |
rp_count <= rp_count - 1'b1; |
end |
//****************************************************************************** |
// rcd_count |
// ACTIVE to READ/WRITE delay - Minimum interval between ACTIVE and READ/WRITE command. |
//****************************************************************************** |
|
always @( negedge clk ) begin |
if ( rst180_r ) |
rcd_count <= 3'b000; |
else if ( current_state == ACTIVE ) |
rcd_count <= 3'b001; |
else if ( rcd_count != 3'b000 ) |
rcd_count <= rcd_count - 1'b1; |
end |
|
|
//****************************************************************************** |
// WR Counter a PRECHARGE command can be applied only after 3 cycles after a |
// WRITE command has finished executing |
//****************************************************************************** |
|
always @(negedge clk) begin |
if (rst180_r) |
wr_count <= 3'b000; |
else |
if (dqs_enable_int) |
wr_count <= wr ; |
else if (wr_count != 3'b000) |
wr_count <= wr_count - 3'b001; |
end |
|
//****************************************************************************** |
// autoref_count - This counter is used to issue AUTO REFRESH command to |
// the memory for every 7.8125us. |
// (Auto Refresh Request is raised for every 7.7 us to allow for termination |
// of any ongoing bus transfer).For example at 166MHz frequency |
// autoref_count = refresh_time_period/clock_period = 7.7us/6.02ns = 1279 |
//****************************************************************************** |
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) begin |
rfc_counter_value <= `RFC_COUNT_VALUE; |
ref_freq_cnt <= `MAX_REF_CNT; |
autoref_value <= 1'b0; |
end |
else begin |
rfc_counter_value <= `RFC_COUNT_VALUE; |
ref_freq_cnt <= `MAX_REF_CNT; |
autoref_value <= (autoref_count == ref_freq_cnt); |
end |
end |
|
always @(negedge clk) begin |
if(rst180_r) |
autoref_count <= `MAX_REF_WIDTH'b0; |
else if(autoref_value) |
autoref_count <= `MAX_REF_WIDTH'b0; |
else |
autoref_count <= autoref_count + 1'b1; |
end |
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) begin |
auto_ref_detect1 <= 1'b0; |
auto_ref1 <= 1'b0; |
end |
else begin |
auto_ref_detect1 <= autoref_value && init_done; |
auto_ref1 <= auto_ref_detect1; |
end |
end |
|
assign ar_done_p = (ar_done_reg == 1'b1) ? 1'b1 : 1'b0; |
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) begin |
auto_ref_wait <= 1'b0; |
ar_done <= 1'b0; |
auto_ref_issued <= 1'b0; |
end |
else begin |
if (auto_ref1 && !auto_ref_wait) |
auto_ref_wait <= 1'b1; |
else if (auto_ref_issued_p) |
auto_ref_wait <= 1'b0; |
else |
auto_ref_wait <= auto_ref_wait; |
|
ar_done <= ar_done_p; |
auto_ref_issued <= auto_ref_issued_p; |
end |
end |
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) begin |
auto_ref_wait1 <= 1'b0; |
auto_ref_wait2 <= 1'b0; |
auto_ref <= 1'b0; |
end |
else begin |
if (auto_ref_issued_p) begin |
auto_ref_wait1 <= 1'b0; |
auto_ref_wait2 <= 1'b0; |
auto_ref <= 1'b0; |
end |
else begin |
auto_ref_wait1 <= auto_ref_wait; |
auto_ref_wait2 <= auto_ref_wait1; |
auto_ref <= auto_ref_wait2; |
end |
end |
end |
|
assign auto_ref_req = auto_ref_wait; |
assign auto_ref_issued_p = (current_state == AUTO_REFRESH); |
|
//****************************************************************************** |
// Common counter for the Initialization sequence |
//****************************************************************************** |
always @(negedge clk) begin |
if(rst180_r) |
count6 <= 8'd0; |
else if(init_current_state == INIT_AUTO_REFRESH || init_current_state == |
INIT_PRECHARGE || init_current_state == INIT_LOAD_MODE_REG) |
count6 <= `RFC_COUNT_VALUE; |
else if(count6 != 8'd0) |
count6 <= count6 - 1'b1; |
else |
count6 <= 8'd0; |
end |
|
//****************************************************************************** |
// While doing consecutive READs or WRITEs, the burst_cnt_max value determines |
// when the next READ or WRITE command should be issued. burst_cnt_max shows the |
// number of clock cycles for each burst. |
// e.g burst_cnt_max = 2 for a burst length of 4 |
// = 4 for a burst length of 8 |
//****************************************************************************** |
assign burst_cnt_max = (burst_length == 3'b010) ? 3'b010 : |
(burst_length == 3'b011) ? 3'b100 : |
3'b000; |
|
always @( negedge clk) begin |
if(rst180_r) |
cas_count <= 3'b000; |
else if(current_state == BURST_READ) |
cas_count <= burst_cnt_max - 1'b1; |
else if(cas_count != 3'b000) |
cas_count <= cas_count - 1'b1; |
end |
|
|
always @( negedge clk ) begin |
if(rst180_r) |
wrburst_end_cnt <= 3'b000; |
else if((current_state == FIRST_WRITE) || (current_state == BURST_WRITE)) |
wrburst_end_cnt <= burst_cnt_max; |
else if(wrburst_end_cnt != 3'b000) |
wrburst_end_cnt <= wrburst_end_cnt - 1'b1; |
end |
|
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) |
rdburst_end_1 <= 1'b0; |
else begin |
rdburst_end_2 <= rdburst_end_1; |
if (burst_done == 1'b1) |
rdburst_end_1 <= 1'b1; |
else |
rdburst_end_1 <= 1'b0; |
end |
end |
|
assign rdburst_end = rdburst_end_1 || rdburst_end_2 ; |
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) |
wrburst_end_1 <= 1'b0; |
else begin |
wrburst_end_2 <= wrburst_end_1; |
wrburst_end_3 <= wrburst_end_2; |
if (burst_done == 1'b1) |
wrburst_end_1 <= 1'b1; |
else |
wrburst_end_1 <= 1'b0; |
end |
end |
|
assign wrburst_end = wrburst_end_1 || wrburst_end_2 || wrburst_end_3; |
|
//****************************************************************************** |
// dqs_enable and dqs_reset signals are used to generate DQS signal during write |
// data. |
//****************************************************************************** |
|
|
|
assign dqs_enable = dqs_enable2; |
assign dqs_reset = dqs_reset2_clk0; |
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) begin |
dqs_enable_int <= 1'b0; |
dqs_reset_int <= 1'b0; |
end |
else begin |
dqs_enable_int <= ((current_state == FIRST_WRITE) || |
(current_state == BURST_WRITE) || |
(wrburst_end_cnt != 3'b000)); |
dqs_reset_int <= (current_state == FIRST_WRITE); |
end |
end |
|
always @ (posedge clk) begin |
if (rst0_r == 1'b1) begin |
dqs_enable1 <= 1'b0; |
dqs_enable2 <= 1'b0; |
dqs_enable3 <= 1'b0; |
dqs_reset1_clk0 <= 1'b0; |
dqs_reset2_clk0 <= 1'b0; |
dqs_reset3_clk0 <= 1'b0; |
end |
else begin |
dqs_enable1 <= dqs_enable_int; |
dqs_enable2 <= dqs_enable1; |
dqs_enable3 <= dqs_enable2; |
dqs_reset1_clk0 <= dqs_reset_int; |
dqs_reset2_clk0 <= dqs_reset1_clk0; |
dqs_reset3_clk0 <= dqs_reset2_clk0; |
end |
end |
|
//****************************************************************************** |
//Write Enable signal to the datapath |
//****************************************************************************** |
|
|
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) |
write_enable <= 1'b0; |
else if(wrburst_end_cnt != 3'b000) |
write_enable <= 1'b1; |
else |
write_enable <= 1'b0; |
end |
|
assign cmd_ack = ack_reg; |
|
FD ack_reg_inst1 |
( |
.Q (ack_reg), |
.D (ack_o), |
.C (~clk) |
); |
|
|
assign ack_o = ((write_cmd_in == 1'b1) || (write_cmd1 == 1'b1) || |
(read_cmd_in == 1'b1) || (read_cmd1 == 1'b1)); |
|
//****************************************************************************** |
// init_done will be asserted when initialization sequence is complete |
//****************************************************************************** |
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) begin |
init_memory <= 1'b0; |
init_done <= 1'b0; |
init_done_r1 <= 1'b0; |
end |
else begin |
init_memory <= init_mem; |
init_done <= init_done_value && (init_count == 4'b1011); |
init_done_r1 <= init_done; |
end |
end |
|
//synthesis translate_off |
always @ (negedge clk) begin |
if (rst180_r == 1'b0) |
if (init_done == 1'b1 && init_done_r1 == 1'b0) |
$display ("INITIALIZATION_DONE"); |
end |
//synthesis translate_on |
|
always @ (negedge clk) begin |
if (init_cmd_in) |
init_pre_count <= 7'b101_0000; |
else |
init_pre_count <= init_pre_count - 7'h1; |
end |
|
always @( negedge clk ) begin |
if ( rst180_r ) |
init_mem <= 1'b0; |
else if ( init_cmd_in ) |
init_mem <= 1'b1; |
else if ( (init_count == 4'b1011) && (count6 == 8'd0 )) |
init_mem <= 1'b0; |
else |
init_mem <= init_mem; |
end |
|
always @( negedge clk ) begin |
if ( rst180_r ) |
init_count <= 4'b0; |
else if (((init_current_state == INIT_PRECHARGE) || |
(init_current_state == INIT_LOAD_MODE_REG) |
|| (init_current_state == INIT_AUTO_REFRESH)) |
&& init_memory == 1'b1) |
init_count <= init_count + 1'b1; |
else |
init_count <= init_count; |
end |
|
assign init_done_value = (dll_rst_count == 8'b0000_0001) ; |
|
|
//Counter to count 200 clock cycles When DLL reset is issued during |
//initialization. |
|
always @( negedge clk ) begin |
if( rst180_r ) |
dll_rst_count <= 8'd0; |
else if(init_count == 4'b0100) |
dll_rst_count <= 8'd200; |
else if(dll_rst_count != 8'b0000_0001) |
dll_rst_count <= dll_rst_count - 8'b0000_0001; |
else |
dll_rst_count <= dll_rst_count; |
end |
|
|
|
assign go_to_active_value =((write_cmd_in == 1'b1) && (accept_cmd_in == 1'b1)) |
|| ((read_cmd_in == 1'b1) && (accept_cmd_in == 1'b1)) |
? 1'b1 : 1'b0; |
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) |
go_to_active <= 1'b0; |
else |
go_to_active <= go_to_active_value; |
end |
|
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) begin |
rfc_count_reg <= 1'b0; |
ar_done_reg <= 1'b0; |
end |
else begin |
if(rfc_count == 8'd2) |
ar_done_reg <= 1'b1; |
else |
ar_done_reg <= 1'b0; |
if(ar_done_reg == 1'b1) |
rfc_count_reg <= 1'b1; |
else if(init_done == 1'b1 && init_mem == 1'b0 && |
rfc_count == 8'd0) |
rfc_count_reg <= 1'b1; |
else if (auto_ref_issued == 1'b1) |
rfc_count_reg <= 1'b0; |
else |
rfc_count_reg <= rfc_count_reg; |
end |
end |
|
|
|
//****************************************************************************** |
// Initialization state machine |
//****************************************************************************** |
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) |
init_current_state <= INIT_IDLE; |
else |
init_current_state <= init_next_state; |
end |
|
always @ (*) begin |
if (rst180_r == 1'b1) |
init_next_state = INIT_IDLE; |
else begin |
case (init_current_state) |
INIT_IDLE : begin |
if (init_memory == 1'b1) begin |
case (init_count) |
4'b0000 : begin |
if(init_pre_count == 7'b000_0001) |
init_next_state = INIT_PRECHARGE; |
else |
init_next_state = INIT_IDLE; |
end |
4'b0001 : begin |
if (count6 == 8'd0) |
init_next_state = INIT_LOAD_MODE_REG; |
else |
init_next_state = INIT_IDLE; |
end |
4'b0010 : begin |
if (count6 == 8'd0) |
init_next_state = INIT_LOAD_MODE_REG; |
else |
init_next_state = INIT_IDLE; |
end |
4'b0011 : begin |
if (count6 == 8'd0) |
init_next_state = INIT_LOAD_MODE_REG; |
else |
init_next_state = INIT_IDLE; |
end |
4'b0100 : begin |
if (count6 == 8'd0) |
init_next_state = INIT_LOAD_MODE_REG; |
else |
init_next_state = INIT_IDLE; |
end |
4'b0101 : begin |
if (count6 == 8'd0) |
init_next_state = INIT_PRECHARGE; |
else |
init_next_state = INIT_IDLE; |
end |
4'b0110 : begin |
if (count6 == 8'd0) |
init_next_state = INIT_AUTO_REFRESH; |
else |
init_next_state = INIT_IDLE; |
end |
4'b0111: begin |
if (count6 == 8'd0) |
init_next_state = INIT_AUTO_REFRESH; |
else |
init_next_state = INIT_IDLE; |
end |
4'b1000: begin |
if (count6 == 8'd0) |
init_next_state = INIT_LOAD_MODE_REG; |
else |
init_next_state = INIT_IDLE; |
end |
4'b1001: begin |
if (count6 == 8'd0) |
init_next_state = INIT_LOAD_MODE_REG; |
else |
init_next_state = init_current_state; |
end |
4'b1010: begin |
if (count6 == 8'd0) |
init_next_state = INIT_LOAD_MODE_REG; |
else |
init_next_state = init_current_state; |
end |
4'b1011: begin |
if (count6 == 8'd0) |
init_next_state = INIT_IDLE; |
else |
init_next_state = init_current_state; |
end |
default : |
init_next_state = INIT_IDLE; |
endcase |
end |
else |
init_next_state = INIT_IDLE; |
end |
INIT_PRECHARGE : |
init_next_state = INIT_IDLE; |
|
INIT_LOAD_MODE_REG : |
init_next_state = INIT_IDLE; |
|
INIT_AUTO_REFRESH : |
init_next_state = INIT_IDLE; |
|
default : |
init_next_state = INIT_IDLE; |
endcase |
end |
end |
|
//****************************************************************************** |
// Main state machine |
//****************************************************************************** |
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) |
current_state <= IDLE; |
else |
current_state <= next_state; |
end |
|
|
always @ (*) begin |
if (rst180_r == 1'b1) |
next_state = IDLE; |
else begin |
case (current_state) |
IDLE : begin |
if(~init_mem) begin |
if ( auto_ref == 1'b1 && rfc_count_reg == 1'b1 |
&& rp_count == 3'd0 ) |
next_state = AUTO_REFRESH; |
else if (go_to_active == 1'b1) |
next_state = ACTIVE; |
else |
next_state = IDLE; |
end |
else |
next_state = IDLE; |
end |
|
PRECHARGE : |
next_state = IDLE; |
|
AUTO_REFRESH : |
next_state = IDLE; |
|
ACTIVE : |
next_state = ACTIVE_WAIT; |
|
ACTIVE_WAIT : begin |
if(rcd_count == 3'b000 && write_cmd1) |
next_state = FIRST_WRITE; |
else if (rcd_count == 3'b000 && read_cmd3) |
next_state = BURST_READ; |
else |
next_state = ACTIVE_WAIT; |
end |
|
FIRST_WRITE : begin |
next_state = WRITE_WAIT; |
end |
|
WRITE_WAIT : begin |
case(wrburst_end) |
1'b1 : |
next_state = PRECHARGE_AFTER_WRITE; |
1'b0 : begin |
if (wrburst_end_cnt == 3'b010) |
next_state = BURST_WRITE; |
else |
next_state = WRITE_WAIT; |
end |
default : |
next_state = WRITE_WAIT; |
endcase |
end |
BURST_WRITE : begin |
next_state = WRITE_WAIT; |
end |
PRECHARGE_AFTER_WRITE : begin |
next_state = PRECHARGE_AFTER_WRITE_2; |
end |
PRECHARGE_AFTER_WRITE_2 : begin |
if(wr_count == 3'd0 && ras_count == 5'd0) |
next_state = PRECHARGE; |
else |
next_state = PRECHARGE_AFTER_WRITE_2; |
end |
READ_WAIT : begin |
case(rdburst_end) |
1'b1 : |
next_state = PRECHARGE_AFTER_WRITE; |
1'b0 : begin |
if (cas_count == 3'b001) |
next_state = BURST_READ; |
else |
next_state = READ_WAIT; |
end |
default : |
next_state = READ_WAIT; |
endcase |
end |
BURST_READ : begin |
next_state = READ_WAIT; |
end |
default : |
next_state = IDLE; |
endcase |
end |
end |
|
//****************************************************************************** |
// Address generation logic |
//****************************************************************************** |
always @( negedge clk ) begin |
if(rst180_r) |
ddr_address1 <= {`ROW_ADDRESS{1'b0}}; |
else if(init_mem) |
case ( init_count ) |
4'b0000, 4'b0101 : ddr_address1 <= {`ROW_ADDRESS{1'b0}} | |
12'h400; |
4'b0001 : ddr_address1 <= {`ROW_ADDRESS{1'b0}}; |
4'b0010 : ddr_address1 <= {`ROW_ADDRESS{1'b0}}; |
4'b0011 : ddr_address1 <= emr; |
4'b0100 : ddr_address1 <= lmr_dll_rst; |
4'b1000 : ddr_address1 <= lmr_dll_set; |
4'b1001 : ddr_address1 <= emr | 12'h380; |
4'b1010 : ddr_address1 <= emr & 12'hc7f; |
default : ddr_address1 <= {`ROW_ADDRESS{1'b0}}; |
endcase |
else if ( current_state == PRECHARGE || |
init_current_state == INIT_PRECHARGE ) |
ddr_address1 <= {`ROW_ADDRESS{1'b0}} | 12'h400; |
else if ( current_state == ACTIVE ) |
ddr_address1 <= row_address_reg; |
else if ( current_state == BURST_WRITE || current_state == FIRST_WRITE || |
current_state == BURST_READ ) |
ddr_address1 <= column_address_reg1; |
else |
ddr_address1 <= `ROW_ADDRESS'b0; |
end |
|
always @( negedge clk ) begin |
if ( rst180_r ) |
ddr_ba1 <= {{`BANK_ADDRESS-1{1'b0}},1'b0}; |
else if ( init_mem ) |
case ( init_count ) |
4'b0001 : ddr_ba1 <= (`BANK_ADDRESS'b10); |
4'b0010 : ddr_ba1 <= (`BANK_ADDRESS'b11); |
4'b0011 , 4'b1001 , 4'b1010 : ddr_ba1 <= (`BANK_ADDRESS'b01); |
default : ddr_ba1 <= {{`BANK_ADDRESS-1{1'b0}},1'b0}; |
endcase |
else if ( current_state == ACTIVE || current_state == FIRST_WRITE || |
current_state == BURST_WRITE || current_state == BURST_READ) |
ddr_ba1 <= ba_address_reg2; |
else |
ddr_ba1 <= `BANK_ADDRESS'b0; |
end |
|
|
always @( negedge clk ) begin |
if ( rst180_r ) |
odt_deassert <= 1'b0; |
else if (wrburst_end_3) |
odt_deassert <= 1'b1; |
else if(!write_cmd3) |
odt_deassert <= 1'b0; |
else |
odt_deassert <= odt_deassert; |
end |
|
assign ddr_odt1 = ( write_cmd3 == 1'b1 && (emr[6]|emr[2]) && !odt_deassert ) |
? 1'b1 : 1'b0; |
|
//****************************************************************************** |
// Register column address |
//****************************************************************************** |
always @ (negedge clk) |
column_address_reg1 <= column_address_reg; |
|
//****************************************************************************** |
//Pipeline stages for ddr_address and ddr_ba |
//****************************************************************************** |
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) begin |
ddr_odt2 <= 1'b0; |
ddr_rasb2 <= 1'b1; |
ddr_casb2 <= 1'b1; |
ddr_web2 <= 1'b1; |
end |
else begin |
ddr_odt2 <= ddr_odt1; |
ddr_rasb2 <= ddr_rasb1; |
ddr_casb2 <= ddr_casb1; |
ddr_web2 <= ddr_web1; |
end |
end |
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) |
ddr_odt_cntrl <= 1'b0; |
else |
ddr_odt_cntrl <= ddr_odt2; |
end |
|
//****************************************************************************** |
// Control signals to the Memory |
//****************************************************************************** |
|
assign ddr_rasb1 = ~((current_state == ACTIVE) || |
(current_state == PRECHARGE) || |
(current_state == AUTO_REFRESH) || |
(init_current_state == INIT_PRECHARGE) || |
(init_current_state == INIT_AUTO_REFRESH) || |
(init_current_state == INIT_LOAD_MODE_REG)); |
|
assign ddr_casb1 = ~((current_state == BURST_READ) || |
(current_state == BURST_WRITE) |
|| (current_state == FIRST_WRITE) || |
(current_state == AUTO_REFRESH) || |
(init_current_state == INIT_AUTO_REFRESH) || |
(init_current_state == INIT_LOAD_MODE_REG)); |
|
assign ddr_web1 = ~((current_state == BURST_WRITE) || |
(current_state == FIRST_WRITE) || |
(current_state == PRECHARGE) || |
(init_current_state == INIT_PRECHARGE) || |
(init_current_state == INIT_LOAD_MODE_REG)); |
|
//****************************************************************************** |
// Register CONTROL SIGNALS outputs |
//****************************************************************************** |
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) |
dqs_div_cascount <= 3'b0; |
else if ((ddr_rasb2 == 1'b1) && (ddr_casb2 == 1'b0) && (ddr_web2 == 1'b1)) |
dqs_div_cascount <= burst_cnt_max ; |
else if (dqs_div_cascount != 3'b000) |
dqs_div_cascount <= dqs_div_cascount - 1'b1; |
else |
dqs_div_cascount <= dqs_div_cascount; |
end |
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) |
dqs_div_rdburstcount <= 3'b000; |
else begin |
if ((dqs_div_cascount == 3'b001) && (burst_length== 3'b010)) |
dqs_div_rdburstcount <= 3'b010; |
else if ((dqs_div_cascount == 3'b011) && (burst_length== 3'b011)) |
dqs_div_rdburstcount <= 3'b100; |
else begin |
if (dqs_div_rdburstcount != 3'b000) |
dqs_div_rdburstcount <= dqs_div_rdburstcount - 1'b1; |
else |
dqs_div_rdburstcount <= dqs_div_rdburstcount; |
end |
end |
end |
|
always @ (negedge clk) begin |
if (rst180_r == 1'b1) |
rst_dqs_div_r <= 1'b0; |
else begin |
if (dqs_div_cascount == 3'b001 && burst_length == 3'b010) |
rst_dqs_div_r <= 1'b1; |
else if (dqs_div_cascount == 3'b011 && burst_length == 3'b011) |
rst_dqs_div_r <= 1'b1; |
else if (dqs_div_rdburstcount == 3'b001 && dqs_div_cascount == 3'b000) |
rst_dqs_div_r <= 1'b0; |
else |
rst_dqs_div_r <= rst_dqs_div_r; |
end |
end // always @ (negedge clk) |
|
always @ (negedge clk) |
rst_dqs_div_r1 <= rst_dqs_div_r; |
|
always @( negedge clk ) begin |
if(dqs_div_cascount != 3'b0 || dqs_div_rdburstcount != 3'b0 ) |
rst_calib <= 1'b1; |
else |
rst_calib <= 1'b0; |
end |
|
(* IOB = "FORCE" *) FD rst_iob_out |
( |
.Q(rst_dqs_div_int1), |
.D(rst_dqs_div_r), |
.C(clk) |
)/* synthesis syn_useioff = 1 */; |
|
|
//Read fifo read enable logic, this signal is same as rst_dqs_div_int signal for RDIMM |
//and one clock ahead of rst_dqs_div_int for component or UDIMM OR SODIMM. |
|
always @(negedge clk) |
read_fifo_rden <= rst_dqs_div_r1; |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_cache.v
0,0 → 1,192
/******************************************************************************* |
* This file is owned and controlled by Xilinx and must be used * |
* solely for design, simulation, implementation and creation of * |
* design files limited to Xilinx devices or technologies. Use * |
* with non-Xilinx devices or technologies is expressly prohibited * |
* and immediately terminates your license. * |
* * |
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" * |
* SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR * |
* XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION * |
* AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION * |
* OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS * |
* IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, * |
* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE * |
* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY * |
* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE * |
* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR * |
* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF * |
* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * |
* FOR A PARTICULAR PURPOSE. * |
* * |
* Xilinx products are not intended for use in life support * |
* appliances, devices, or systems. Use in such applications are * |
* expressly prohibited. * |
* * |
* (c) Copyright 1995-2011 Xilinx, Inc. * |
* All rights reserved. * |
*******************************************************************************/ |
// You must compile the wrapper file s3adsp_ddr2_cache.v when simulating |
// the core, s3adsp_ddr2_cache. When compiling the wrapper file, be sure to |
// reference the XilinxCoreLib Verilog simulation library. For detailed |
// instructions, please refer to the "CORE Generator Help". |
|
// The synthesis directives "translate_off/translate_on" specified below are |
// supported by Xilinx, Mentor Graphics and Synplicity synthesis |
// tools. Ensure they are correct for your synthesis tool(s). |
|
`timescale 1ns/1ps |
|
module s3adsp_ddr2_cache( |
clka, |
ena, |
wea, |
addra, |
dina, |
douta, |
clkb, |
enb, |
web, |
addrb, |
dinb, |
doutb |
); |
|
input clka; |
input ena; |
input [3 : 0] wea; |
input [9 : 0] addra; |
input [31 : 0] dina; |
output [31 : 0] douta; |
input clkb; |
input enb; |
input [7 : 0] web; |
input [8 : 0] addrb; |
input [63 : 0] dinb; |
output [63 : 0] doutb; |
|
// synthesis translate_off |
|
BLK_MEM_GEN_V6_1 #( |
.C_ADDRA_WIDTH(10), |
.C_ADDRB_WIDTH(9), |
.C_ALGORITHM(1), |
.C_AXI_ID_WIDTH(4), |
.C_AXI_SLAVE_TYPE(0), |
.C_AXI_TYPE(1), |
.C_BYTE_SIZE(8), |
.C_COMMON_CLK(0), |
.C_DEFAULT_DATA("0"), |
.C_DISABLE_WARN_BHV_COLL(1), |
.C_DISABLE_WARN_BHV_RANGE(0), |
.C_FAMILY("spartan3"), |
.C_HAS_AXI_ID(0), |
.C_HAS_ENA(1), |
.C_HAS_ENB(1), |
.C_HAS_INJECTERR(0), |
.C_HAS_MEM_OUTPUT_REGS_A(0), |
.C_HAS_MEM_OUTPUT_REGS_B(0), |
.C_HAS_MUX_OUTPUT_REGS_A(0), |
.C_HAS_MUX_OUTPUT_REGS_B(0), |
.C_HAS_REGCEA(0), |
.C_HAS_REGCEB(0), |
.C_HAS_RSTA(0), |
.C_HAS_RSTB(0), |
.C_HAS_SOFTECC_INPUT_REGS_A(0), |
.C_HAS_SOFTECC_OUTPUT_REGS_B(0), |
.C_INIT_FILE_NAME("no_coe_file_loaded"), |
.C_INITA_VAL("0"), |
.C_INITB_VAL("0"), |
.C_INTERFACE_TYPE(0), |
.C_LOAD_INIT_FILE(0), |
.C_MEM_TYPE(2), |
.C_MUX_PIPELINE_STAGES(0), |
.C_PRIM_TYPE(1), |
.C_READ_DEPTH_A(1024), |
.C_READ_DEPTH_B(512), |
.C_READ_WIDTH_A(32), |
.C_READ_WIDTH_B(64), |
.C_RST_PRIORITY_A("CE"), |
.C_RST_PRIORITY_B("CE"), |
.C_RST_TYPE("SYNC"), |
.C_RSTRAM_A(0), |
.C_RSTRAM_B(0), |
.C_SIM_COLLISION_CHECK("NONE"), |
.C_USE_BYTE_WEA(1), |
.C_USE_BYTE_WEB(1), |
.C_USE_DEFAULT_DATA(0), |
.C_USE_ECC(0), |
.C_USE_SOFTECC(0), |
.C_WEA_WIDTH(4), |
.C_WEB_WIDTH(8), |
.C_WRITE_DEPTH_A(1024), |
.C_WRITE_DEPTH_B(512), |
.C_WRITE_MODE_A("WRITE_FIRST"), |
.C_WRITE_MODE_B("WRITE_FIRST"), |
.C_WRITE_WIDTH_A(32), |
.C_WRITE_WIDTH_B(64), |
.C_XDEVICEFAMILY("spartan3adsp") |
) |
inst ( |
.CLKA(clka), |
.ENA(ena), |
.WEA(wea), |
.ADDRA(addra), |
.DINA(dina), |
.DOUTA(douta), |
.CLKB(clkb), |
.ENB(enb), |
.WEB(web), |
.ADDRB(addrb), |
.DINB(dinb), |
.DOUTB(doutb), |
.RSTA(), |
.REGCEA(), |
.RSTB(), |
.REGCEB(), |
.INJECTSBITERR(), |
.INJECTDBITERR(), |
.SBITERR(), |
.DBITERR(), |
.RDADDRECC(), |
.S_ACLK(), |
.S_ARESETN(), |
.S_AXI_AWID(), |
.S_AXI_AWADDR(), |
.S_AXI_AWLEN(), |
.S_AXI_AWSIZE(), |
.S_AXI_AWBURST(), |
.S_AXI_AWVALID(), |
.S_AXI_AWREADY(), |
.S_AXI_WDATA(), |
.S_AXI_WSTRB(), |
.S_AXI_WLAST(), |
.S_AXI_WVALID(), |
.S_AXI_WREADY(), |
.S_AXI_BID(), |
.S_AXI_BRESP(), |
.S_AXI_BVALID(), |
.S_AXI_BREADY(), |
.S_AXI_ARID(), |
.S_AXI_ARADDR(), |
.S_AXI_ARLEN(), |
.S_AXI_ARSIZE(), |
.S_AXI_ARBURST(), |
.S_AXI_ARVALID(), |
.S_AXI_ARREADY(), |
.S_AXI_RID(), |
.S_AXI_RDATA(), |
.S_AXI_RRESP(), |
.S_AXI_RLAST(), |
.S_AXI_RVALID(), |
.S_AXI_RREADY(), |
.S_AXI_INJECTSBITERR(), |
.S_AXI_INJECTDBITERR(), |
.S_AXI_SBITERR(), |
.S_AXI_DBITERR(), |
.S_AXI_RDADDRECC() |
); |
|
// synthesis translate_on |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_data_path_0.v
0,0 → 1,144
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_data_path_0.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:41 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This module has the write and read data paths for the |
// DDR2 memory interface. The write data along with write enable |
// signals are forwarded to the DDR IOB FFs. The read data is |
// captured in CLB FFs and finally input to FIFOs. |
//***************************************************************************** |
|
`include "s3adsp_ddr2_parameters_0.v" |
`timescale 1ns/100ps |
module s3adsp_ddr2_data_path_0 |
( |
input [((`DATA_WIDTH*2)-1):0] user_input_data, |
input [((`DATA_MASK_WIDTH*2) -1):0] user_data_mask, |
input clk, |
input clk90, |
input reset, |
input reset90, |
input write_enable, |
input rst_dqs_div_in, |
input [4:0] delay_sel, |
input [(`DATA_WIDTH-1):0] dq, |
input [(`DATA_STROBE_WIDTH-1):0] dqs_int_delay_in, |
input read_fifo_rden, // Added new signal |
output u_data_val, |
output [((`DATA_WIDTH*2)-1):0] user_output_data, |
output write_en_val, |
output [((`DATA_MASK_WIDTH)-1):0] data_mask_f, |
output [((`DATA_MASK_WIDTH)-1):0] data_mask_r, |
output [(`DATA_WIDTH-1):0] write_data_falling, |
output [(`DATA_WIDTH-1):0] write_data_rising, |
//debug_signals |
input [4:0] vio_out_dqs, |
input vio_out_dqs_en, |
input [4:0] vio_out_rst_dqs_div, |
input vio_out_rst_dqs_div_en |
); |
|
wire [(4*`DATA_STROBE_WIDTH)-1:0] fifo_0_wr_addr; |
wire [(4*`DATA_STROBE_WIDTH)-1:0] fifo_1_wr_addr; |
wire [(`DATA_STROBE_WIDTH-1):0] dqs_delayed_col0; |
wire [(`DATA_STROBE_WIDTH-1):0] dqs_delayed_col1; |
wire [(`DATA_STROBE_WIDTH-1):0] fifo_0_wr_en/* synthesis syn_keep=1 */; |
wire [(`DATA_STROBE_WIDTH-1):0] fifo_1_wr_en/* synthesis syn_keep=1 */; |
|
s3adsp_ddr2_data_read_0 data_read0 |
( |
.clk90 (clk90), |
.reset90 (reset90), |
.ddr_dq_in (dq), |
.fifo_0_wr_en (fifo_0_wr_en), |
.fifo_1_wr_en (fifo_1_wr_en), |
.fifo_0_wr_addr (fifo_0_wr_addr), |
.fifo_1_wr_addr (fifo_1_wr_addr), |
.dqs_delayed_col0 (dqs_delayed_col0), |
.dqs_delayed_col1 (dqs_delayed_col1), |
.read_fifo_rden (read_fifo_rden), |
.user_output_data (user_output_data), |
.u_data_val (u_data_val) |
); |
s3adsp_ddr2_data_read_controller_0 data_read_controller0 |
( |
.clk (clk), |
.reset (reset), |
.rst_dqs_div_in (rst_dqs_div_in), |
.delay_sel (delay_sel), |
.dqs_int_delay_in (dqs_int_delay_in), |
.fifo_0_wr_en_val (fifo_0_wr_en), |
.fifo_1_wr_en_val (fifo_1_wr_en), |
.fifo_0_wr_addr_val (fifo_0_wr_addr), |
.fifo_1_wr_addr_val (fifo_1_wr_addr), |
.dqs_delayed_col0_val (dqs_delayed_col0), |
.dqs_delayed_col1_val (dqs_delayed_col1), |
//debug_signals |
.vio_out_dqs (vio_out_dqs), |
.vio_out_dqs_en (vio_out_dqs_en), |
.vio_out_rst_dqs_div (vio_out_rst_dqs_div), |
.vio_out_rst_dqs_div_en (vio_out_rst_dqs_div_en) |
); |
|
|
s3adsp_ddr2_data_write_0 data_write0 |
( |
.user_input_data (user_input_data), |
.user_data_mask (user_data_mask), |
.clk90 (clk90), |
.write_enable (write_enable), |
.write_en_val (write_en_val), |
.write_data_falling (write_data_falling), |
.write_data_rising (write_data_rising), |
.data_mask_f (data_mask_f), |
.data_mask_r (data_mask_r) |
); |
|
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_dqs_delay.v
0,0 → 1,148
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_dqs_delay.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:41 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This module generates the delay in the dqs signal. |
//***************************************************************************** |
|
`timescale 1ns/100ps |
module s3adsp_ddr2_dqs_delay |
( |
input clk_in, |
input [4:0] sel_in, |
output clk_out |
); |
|
wire delay1; |
wire delay2; |
wire delay3; |
wire delay4; |
wire delay5; |
|
localparam HIGH = 1'b1; |
|
LUT4 # |
( |
.INIT (16'hf3c0) |
) |
one |
( |
.I0 (HIGH), |
.I1 (sel_in[4]), |
.I2 (delay5), |
.I3 (clk_in), |
.O (clk_out) |
); |
|
LUT4 # |
( |
.INIT (16'hee22) |
) |
two |
( |
.I0 (clk_in), |
.I1 (sel_in[2]), |
.I2 (HIGH), |
.I3 (delay3), |
.O (delay4) |
); |
|
LUT4 # |
( |
.INIT (16'he2e2) |
) |
three |
( |
.I0 (clk_in), |
.I1 (sel_in[0]), |
.I2 (delay1), |
.I3 (HIGH), |
.O (delay2) |
); |
|
LUT4 # |
( |
.INIT (16'hff00) |
) |
four |
( |
.I0 (HIGH), |
.I1 (HIGH), |
.I2 (HIGH), |
.I3 (clk_in), |
.O (delay1) |
); |
|
LUT4 # |
( |
.INIT (16'hf3c0) |
) |
five |
( |
.I0 (HIGH), |
.I1 (sel_in[3]), |
.I2 (delay4), |
.I3 (clk_in), |
.O (delay5) |
); |
|
LUT4 # |
( |
.INIT (16'he2e2) |
) |
six |
( |
.I0 (clk_in), |
.I1 (sel_in[1]), |
.I2 (delay2), |
.I3 (HIGH), |
.O (delay3) |
); |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/xilinx_s3adsp_ddr2.v
0,0 → 1,214
/* |
* Wrapper for Xilinx MIG'd DDR2 controller, allowing 3 masters |
* to contol the single interface. |
*/ |
|
module xilinx_s3adsp_ddr2 |
( |
// Inputs |
input [31:0] wbm0_adr_i, |
input [1:0] wbm0_bte_i, |
input [2:0] wbm0_cti_i, |
input wbm0_cyc_i, |
input [31:0] wbm0_dat_i, |
input [3:0] wbm0_sel_i, |
|
input wbm0_stb_i, |
input wbm0_we_i, |
|
// Outputs |
output wbm0_ack_o, |
output wbm0_err_o, |
output wbm0_rty_o, |
output [31:0] wbm0_dat_o, |
|
|
// Inputs |
input [31:0] wbm1_adr_i, |
input [1:0] wbm1_bte_i, |
input [2:0] wbm1_cti_i, |
input wbm1_cyc_i, |
input [31:0] wbm1_dat_i, |
input [3:0] wbm1_sel_i, |
|
input wbm1_stb_i, |
input wbm1_we_i, |
|
// Outputs |
output wbm1_ack_o, |
output wbm1_err_o, |
output wbm1_rty_o, |
output [31:0] wbm1_dat_o, |
|
|
|
// Inputs |
input [31:0] wbm2_adr_i, |
input [1:0] wbm2_bte_i, |
input [2:0] wbm2_cti_i, |
input wbm2_cyc_i, |
input [31:0] wbm2_dat_i, |
input [3:0] wbm2_sel_i, |
|
input wbm2_stb_i, |
input wbm2_we_i, |
|
// Outputs |
output wbm2_ack_o, |
output wbm2_err_o, |
output wbm2_rty_o, |
output [31:0] wbm2_dat_o, |
|
input wb_clk, |
input wb_rst, |
|
|
inout [31:0] ddr2_dq, |
output [12:0] ddr2_a, |
output [1:0] ddr2_ba, |
output ddr2_cke, |
output ddr2_cs_n, |
output ddr2_ras_n, |
output ddr2_cas_n, |
output ddr2_we_n, |
output ddr2_odt, |
output [3:0] ddr2_dm, |
inout [3:0] ddr2_dqs, |
inout [3:0] ddr2_dqs_n, |
output [1:0] ddr2_ck, |
output [1:0] ddr2_ck_n, |
input ddr2_rst_dqs_div_in, |
output ddr2_rst_dqs_div_out, |
input clk133_i |
|
); |
|
// Internal wires to actual RAM |
wire [31:0] wbs_ram_adr_i; |
wire [1:0] wbs_ram_bte_i; |
wire [2:0] wbs_ram_cti_i; |
wire wbs_ram_cyc_i; |
wire [31:0] wbs_ram_dat_i; |
wire [3:0] wbs_ram_sel_i; |
wire wbs_ram_stb_i; |
wire wbs_ram_we_i; |
|
wire wbs_ram_ack_o; |
wire [31:0] wbs_ram_dat_o; |
|
reg [2:0] input_select, last_selected; |
wire arb_for_wbm0, arb_for_wbm1, arb_for_wbm2; |
// Wires allowing selection of new input |
assign arb_for_wbm0 = (last_selected[1] | last_selected[2] | |
!wbm1_cyc_i | !wbm2_cyc_i) & !(|input_select); |
assign arb_for_wbm1 = (last_selected[0] | last_selected[2] | |
!wbm0_cyc_i | !wbm2_cyc_i) & !(|input_select); |
assign arb_for_wbm2 = (last_selected[0] | last_selected[1] | |
!wbm0_cyc_i | !wbm1_cyc_i) & !(|input_select); |
|
// Master select logic |
always @(posedge wb_clk) |
if (wb_rst) |
input_select <= 0; |
else if ((input_select[0] & !wbm0_cyc_i) | (input_select[1] & !wbm1_cyc_i) |
| (input_select[2] & !wbm2_cyc_i)) |
input_select <= 0; |
else if (!(&input_select) & wbm0_cyc_i & arb_for_wbm0) |
input_select <= 3'b001; |
else if (!(&input_select) & wbm1_cyc_i & arb_for_wbm1) |
input_select <= 3'b010; |
else if (!(&input_select) & wbm2_cyc_i & arb_for_wbm2) |
input_select <= 3'b100; |
|
always @(posedge wb_clk) |
if (wb_rst) |
last_selected <= 0; |
else if (!(&input_select) & wbm0_cyc_i & arb_for_wbm0) |
last_selected <= 3'b001; |
else if (!(&input_select) & wbm1_cyc_i & arb_for_wbm1) |
last_selected <= 3'b010; |
else if (!(&input_select) & wbm2_cyc_i & arb_for_wbm2) |
last_selected <= 3'b100; |
|
// Mux input signals to RAM (default to wbm0) |
assign wbs_ram_adr_i = (input_select[2]) ? wbm2_adr_i : |
(input_select[1]) ? wbm1_adr_i : |
(input_select[0]) ? wbm0_adr_i : 0; |
assign wbs_ram_bte_i = (input_select[2]) ? wbm2_bte_i : |
(input_select[1]) ? wbm1_bte_i : |
(input_select[0]) ? wbm0_bte_i : 0; |
assign wbs_ram_cti_i = (input_select[2]) ? wbm2_cti_i : |
(input_select[1]) ? wbm1_cti_i : |
(input_select[0]) ? wbm0_cti_i : 0; |
assign wbs_ram_cyc_i = (input_select[2]) ? wbm2_cyc_i : |
(input_select[1]) ? wbm1_cyc_i : |
(input_select[0]) ? wbm0_cyc_i : 0; |
assign wbs_ram_dat_i = (input_select[2]) ? wbm2_dat_i : |
(input_select[1]) ? wbm1_dat_i : |
(input_select[0]) ? wbm0_dat_i : 0; |
assign wbs_ram_sel_i = (input_select[2]) ? wbm2_sel_i : |
(input_select[1]) ? wbm1_sel_i : |
(input_select[0]) ? wbm0_sel_i : 0; |
assign wbs_ram_stb_i = (input_select[2]) ? wbm2_stb_i : |
(input_select[1]) ? wbm1_stb_i : |
(input_select[0]) ? wbm0_stb_i : 0; |
assign wbs_ram_we_i = (input_select[2]) ? wbm2_we_i : |
(input_select[1]) ? wbm1_we_i : |
(input_select[0]) ? wbm0_we_i : 0; |
|
// Output from RAM, gate the ACK, ERR, RTY signals appropriately |
assign wbm0_dat_o = wbs_ram_dat_o; |
assign wbm0_ack_o = wbs_ram_ack_o & input_select[0]; |
assign wbm0_err_o = 0; |
assign wbm0_rty_o = 0; |
|
assign wbm1_dat_o = wbs_ram_dat_o; |
assign wbm1_ack_o = wbs_ram_ack_o & input_select[1]; |
assign wbm1_err_o = 0; |
assign wbm1_rty_o = 0; |
|
assign wbm2_dat_o = wbs_ram_dat_o; |
assign wbm2_ack_o = wbs_ram_ack_o & input_select[2]; |
assign wbm2_err_o = 0; |
assign wbm2_rty_o = 0; |
|
|
xilinx_s3adsp_ddr2_if xilinx_s3adsp_ddr2_if |
( |
.wb_dat_o (wbs_ram_dat_o), |
.wb_ack_o (wbs_ram_ack_o), |
.wb_adr_i (wbs_ram_adr_i[31:0]), |
.wb_stb_i (wbs_ram_stb_i), |
.wb_cti_i (wbs_ram_cti_i), |
.wb_bte_i (wbs_ram_bte_i), |
.wb_cyc_i (wbs_ram_cyc_i), |
.wb_we_i (wbs_ram_we_i), |
.wb_sel_i (wbs_ram_sel_i[3:0]), |
.wb_dat_i (wbs_ram_dat_i[31:0]), |
|
.ddr2_dq (ddr2_dq), |
.ddr2_a (ddr2_a), |
.ddr2_ba (ddr2_ba), |
.ddr2_cke (ddr2_cke), |
.ddr2_cs_n (ddr2_cs_n), |
.ddr2_ras_n (ddr2_ras_n), |
.ddr2_cas_n (ddr2_cas_n), |
.ddr2_we_n (ddr2_we_n), |
.ddr2_odt (ddr2_odt), |
.ddr2_dm (ddr2_dm), |
.ddr2_dqs (ddr2_dqs), |
.ddr2_dqs_n (ddr2_dqs_n), |
.ddr2_ck (ddr2_ck), |
.ddr2_ck_n (ddr2_ck_n), |
.ddr2_rst_dqs_div_in (ddr2_rst_dqs_div_in), |
.ddr2_rst_dqs_div_out (ddr2_rst_dqs_div_out), |
.clk133_i (clk133_i), |
|
.wb_clk (wb_clk), |
.wb_rst (wb_rst)); |
|
|
|
|
endmodule |
|
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_infrastructure_iobs_0.v
0,0 → 1,124
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_infrastructure_iobs_0.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:41 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This module has the FDDRRSE instantiations to the clocks. |
//***************************************************************************** |
|
`include "s3adsp_ddr2_parameters_0.v" |
`timescale 1ns/100ps |
|
module s3adsp_ddr2_infrastructure_iobs_0 |
( |
input clk0, |
output [(`CLK_WIDTH-1):0] ddr2_ck, |
output [(`CLK_WIDTH-1):0] ddr2_ck_n |
); |
|
wire vcc; |
wire gnd; |
|
|
|
wire [`CLK_WIDTH-1 :0] ddr2_clk_q; |
|
assign gnd = 1'b0; |
assign vcc = 1'b1; |
|
//---- *********************************************************** |
//---- Output DDR generation |
//---- This includes instantiation of the output DDR flip flop |
//---- for ddr clk's and dimm clk's |
//---- *********************************************************** |
|
|
|
|
|
genvar clk_i; |
generate |
for(clk_i = 0; clk_i < `CLK_WIDTH; clk_i = clk_i+1) |
begin: gen_clk |
FDDRRSE clk_inst |
( |
.Q (ddr2_clk_q[clk_i]), |
.C0 (clk0), |
.C1 (~clk0), |
.CE (vcc), |
.D0 (vcc), |
.D1 (gnd), |
.R (gnd), |
.S (gnd) |
); |
end |
endgenerate |
|
|
//---- ****************************************** |
//---- Ouput BUffers for ddr clk's and dimm clk's |
//---- ****************************************** |
|
|
|
|
|
genvar obuf_i; |
generate |
for(obuf_i = 0; obuf_i < `CLK_WIDTH; obuf_i = obuf_i+1) |
begin: gen_obuf |
OBUFDS OBUFDS_inst |
( |
.I(ddr2_clk_q[obuf_i]), |
.O(ddr2_ck[obuf_i]), |
.OB(ddr2_ck_n[obuf_i]) |
); |
end |
endgenerate |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_iobs_0.v
0,0 → 1,153
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_iobs_0.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:41 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This module has the instantiations infrastructure_ios, |
// data_path_iobs and controller_iobs modules |
//***************************************************************************** |
|
`include "s3adsp_ddr2_parameters_0.v" |
`timescale 1ns/100ps |
|
(* X_CORE_INFO = "mig_v3_61_ddr2_sp3, Coregen 12.4" , |
CORE_GENERATION_INFO = "ddr2_sp3,mig_v3_61,{component_name=ddr2_sp3, data_width=32, memory_width=8, clk_width=2, bank_address=2, row_address=13, column_address=10, no_of_cs=1, cke_width=1, registered=0, data_mask=1, mask_enable=1, load_mode_register=13'b0010100110011, ext_load_mode_register=13'b0000000000000, language=Verilog, synthesis_tool=ISE, interface_type=DDR2_SDRAM, no_of_controllers=1}" *) |
module s3adsp_ddr2_iobs_0 |
( |
input clk, |
input clk90, |
input ddr_rasb_cntrl, |
input ddr_casb_cntrl, |
input ddr_web_cntrl, |
input ddr_cke_cntrl, |
input ddr_csb_cntrl, |
input ddr_odt_cntrl, |
input [(`ROW_ADDRESS-1):0] ddr_address_cntrl, |
input [(`BANK_ADDRESS-1):0] ddr_ba_cntrl, |
input rst_dqs_div_int, |
input dqs_reset, |
input dqs_enable, |
inout [((`DATA_STROBE_WIDTH)-1):0] ddr_dqs, |
inout [(`DATA_STROBE_WIDTH-1):0] ddr_dqs_n, |
inout [(`DATA_WIDTH-1):0] ddr_dq, |
input [(`DATA_WIDTH-1):0] write_data_falling, |
input [(`DATA_WIDTH-1):0] write_data_rising, |
input write_en_val, |
input [((`DATA_MASK_WIDTH)-1):0] data_mask_f, |
input [((`DATA_MASK_WIDTH)-1):0] data_mask_r, |
output [(`CLK_WIDTH-1):0] ddr2_ck, |
output [(`CLK_WIDTH-1):0] ddr2_ck_n, |
output ddr_rasb, |
output ddr_casb, |
output ddr_web, |
output [(`BANK_ADDRESS-1):0] ddr_ba, |
output [(`ROW_ADDRESS-1):0] ddr_address, |
output ddr_cke, |
output ddr_csb, |
output ddr_odt0, |
output rst_dqs_div, |
input rst_dqs_div_in, |
output rst_dqs_div_out, |
output [(`DATA_STROBE_WIDTH-1):0] dqs_int_delay_in, |
output [((`DATA_MASK_WIDTH)-1):0] ddr_dm, |
output [((`DATA_WIDTH)-1):0] dq |
); |
s3adsp_ddr2_infrastructure_iobs_0 infrastructure_iobs0 |
( |
.ddr2_ck (ddr2_ck), |
.ddr2_ck_n (ddr2_ck_n), |
.clk0 (clk) |
); |
|
s3adsp_ddr2_controller_iobs_0 controller_iobs0 |
( |
.clk0 (clk), |
.ddr_rasb_cntrl (ddr_rasb_cntrl), |
.ddr_casb_cntrl (ddr_casb_cntrl), |
.ddr_web_cntrl (ddr_web_cntrl), |
.ddr_cke_cntrl (ddr_cke_cntrl), |
.ddr_csb_cntrl (ddr_csb_cntrl), |
.ddr_odt_cntrl (ddr_odt_cntrl), |
.ddr_address_cntrl (ddr_address_cntrl), |
.ddr_ba_cntrl (ddr_ba_cntrl), |
.rst_dqs_div_int (rst_dqs_div_int), |
.ddr_rasb (ddr_rasb), |
.ddr_casb (ddr_casb), |
.ddr_web (ddr_web), |
.ddr_ba (ddr_ba), |
.ddr_address (ddr_address), |
.ddr_cke (ddr_cke), |
.ddr_csb (ddr_csb), |
.ddr_odt0 (ddr_odt0), |
.rst_dqs_div (rst_dqs_div), |
.rst_dqs_div_in (rst_dqs_div_in), |
.rst_dqs_div_out (rst_dqs_div_out) |
); |
|
|
s3adsp_ddr2_data_path_iobs_0 datapath_iobs0 |
( |
.clk (clk), |
.clk90 (clk90), |
.dqs_reset (dqs_reset), |
.dqs_enable (dqs_enable), |
.ddr_dqs (ddr_dqs), |
.ddr_dqs_n (ddr_dqs_n), |
.ddr_dq (ddr_dq), |
.write_data_falling (write_data_falling), |
.write_data_rising (write_data_rising), |
.write_en_val (write_en_val), |
.data_mask_f (data_mask_f), |
.data_mask_r (data_mask_r), |
.dqs_int_delay_in (dqs_int_delay_in), |
.ddr_dm (ddr_dm), |
.ddr_dq_val (dq) |
); |
|
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_fifo_0_wr_en_0.v
0,0 → 1,80
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_fifo_0_wr_en_0.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:41 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This module generate the write enable signal to the fifos, |
// which are driven by negedge data strobe. |
//***************************************************************************** |
|
`timescale 1ns/100ps |
module s3adsp_ddr2_fifo_0_wr_en_0 |
( |
input clk, |
input reset, |
input din, |
output rst_dqs_delay_n, |
output dout |
); |
|
localparam TIE_HIGH = 1'b1; |
|
wire din_delay; |
|
assign rst_dqs_delay_n = ~din_delay; |
assign dout = (din | (din_delay)); |
|
|
FDCE delay_ff |
(.Q (din_delay), |
.C (clk), |
.CE (TIE_HIGH), |
.CLR (reset), |
.D (din)); |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_fifo_1_wr_en_0.v
0,0 → 1,84
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_fifo_1_wr_en_0.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:41 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This module generate the write enable signal to the fifos, |
// which are driven by posedge data strobe. |
//***************************************************************************** |
|
`timescale 1ns/100ps |
module s3adsp_ddr2_fifo_1_wr_en_0 |
( |
input clk, |
input rst_dqs_delay_n, |
input reset, |
input din, |
output dout |
); |
|
localparam TIE_HIGH = 1'b1; |
|
wire din_delay; |
wire dout0; |
wire rst_dqs_delay; |
|
assign rst_dqs_delay = ~rst_dqs_delay_n; |
assign dout0 = din & rst_dqs_delay_n; |
assign dout = rst_dqs_delay | din_delay; |
|
FDCE delay_ff_1 |
( |
.Q (din_delay), |
.C (clk), |
.CE (TIE_HIGH), |
.CLR (reset), |
.D (dout0) |
); |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_rd_gray_cntr.v
0,0 → 1,131
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_rd_gray_cntr.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:42 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : |
//***************************************************************************** |
|
`timescale 1ns/100ps |
module s3adsp_ddr2_rd_gray_cntr |
( |
input clk90, |
input reset90, |
input cnt_en, |
output [3:0] rgc_gcnt |
); |
|
wire [3:0] gc_int; |
reg [3:0] d_in; |
reg reset90_r; |
|
assign rgc_gcnt = gc_int; |
|
|
always @( posedge clk90 ) |
reset90_r <= reset90; |
|
always@(gc_int) begin |
case (gc_int) |
4'b0000: d_in <= 4'b0001; //1 |
4'b0001: d_in <= 4'b0011; //3 |
4'b0010: d_in <= 4'b0110; //6 |
4'b0011: d_in <= 4'b0010; //2 |
4'b0100: d_in <= 4'b1100; //c |
4'b0101: d_in <= 4'b0100; //4 |
4'b0110: d_in <= 4'b0111; //7 |
4'b0111: d_in <= 4'b0101; //5 |
4'b1000: d_in <= 4'b0000; //0 |
4'b1001: d_in <= 4'b1000; //8 |
4'b1010: d_in <= 4'b1011; //b |
4'b1011: d_in <= 4'b1001; //9 |
4'b1100: d_in <= 4'b1101; //d |
4'b1101: d_in <= 4'b1111; //f |
4'b1110: d_in <= 4'b1010; //a |
4'b1111: d_in <= 4'b1110; //e |
default : d_in <= 4'b0001; //1 |
endcase |
end |
|
FDRE bit0 |
( |
.Q (gc_int[0]), |
.C (clk90), |
.CE (cnt_en), |
.D (d_in[0]), |
.R (reset90_r) |
); |
|
FDRE bit1 |
( |
.Q (gc_int[1]), |
.C (clk90), |
.CE (cnt_en), |
.D (d_in[1]), |
.R (reset90_r) |
); |
|
FDRE bit2 |
( |
.Q (gc_int[2]), |
.C (clk90), |
.CE (cnt_en), |
.D (d_in[2]), |
.R (reset90_r) |
); |
|
FDRE bit3 |
( |
.Q (gc_int[3]), |
.C (clk90), |
.CE (cnt_en), |
.D (d_in[3]), |
.R (reset90_r) |
); |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_controller_iobs_0.v
0,0 → 1,242
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007, 2008 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_controller_iobs_0.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:41 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This module has the IOB instantiations to address and control |
// signals. |
//***************************************************************************** |
|
`include "s3adsp_ddr2_parameters_0.v" |
`timescale 1ns/100ps |
|
module s3adsp_ddr2_controller_iobs_0 |
( |
input clk0, |
input ddr_rasb_cntrl, |
input ddr_casb_cntrl, |
input ddr_web_cntrl, |
input ddr_cke_cntrl, |
input ddr_csb_cntrl, |
input ddr_odt_cntrl, |
input [`ROW_ADDRESS-1:0] ddr_address_cntrl, |
input [`BANK_ADDRESS-1:0] ddr_ba_cntrl, |
input rst_dqs_div_int, |
output ddr_rasb, |
output ddr_casb, |
output ddr_web, |
output [`BANK_ADDRESS-1:0] ddr_ba, |
output [`ROW_ADDRESS-1:0] ddr_address, |
output ddr_cke, |
output ddr_csb, |
output ddr_odt0, |
output rst_dqs_div, |
input rst_dqs_div_in, |
output rst_dqs_div_out |
); |
|
|
wire ddr_odt_reg; |
wire [`ROW_ADDRESS-1:0] ddr_address_iob_reg; |
wire [`BANK_ADDRESS-1:0] ddr_ba_reg; |
wire ddr_web_q; |
wire ddr_rasb_q; |
wire ddr_casb_q; |
wire ddr_cke_q; |
wire ddr_cke_int; |
|
//---- ******************************************* ---- |
//---- Includes the instantiation of FD for cntrl ---- |
//---- signals ---- |
//---- ******************************************* ---- |
|
(* IOB = "FORCE" *) FD iob_web |
( |
.Q (ddr_web_q), |
.D (ddr_web_cntrl), |
.C (~clk0) |
)/* synthesis syn_useioff = 1 */; |
|
(* IOB = "FORCE" *) FD iob_rasb |
( |
.Q (ddr_rasb_q), |
.D (ddr_rasb_cntrl), |
.C (~clk0) |
)/* synthesis syn_useioff = 1 */; |
|
|
(* IOB = "FORCE" *) FD iob_casb |
( |
.Q (ddr_casb_q), |
.D (ddr_casb_cntrl), |
.C (~clk0) |
)/* synthesis syn_useioff = 1 */; |
|
|
//---- ************************************* ---- |
//---- Output buffers for control signals ---- |
//---- ************************************* ---- |
|
OBUF r16 |
( |
.I (ddr_web_q), |
.O (ddr_web) |
); |
|
OBUF r17 |
( |
.I (ddr_rasb_q), |
.O (ddr_rasb) |
); |
|
OBUF r18 |
( |
.I (ddr_casb_q), |
.O (ddr_casb) |
); |
|
OBUF r19 |
( |
.I (ddr_csb_cntrl), |
.O (ddr_csb) |
); |
|
|
FD iob_cke1 |
( |
.Q (ddr_cke_int), |
.D (ddr_cke_cntrl), |
.C (clk0) |
); |
|
|
(* IOB = "FORCE" *) FD iob_cke |
( |
.Q (ddr_cke_q), |
.D (ddr_cke_int), |
.C (~clk0) |
)/* synthesis syn_useioff = 1 */; |
|
|
OBUF r20 |
( |
.I (ddr_cke_q), |
.O (ddr_cke) |
); |
|
|
(* IOB = "FORCE" *) FD iob_odt |
( |
.Q (ddr_odt_reg), |
.D (ddr_odt_cntrl), |
.C (~clk0) |
)/* synthesis syn_useioff = 1 */; |
|
|
OBUF r21 |
( |
.I (ddr_odt_reg), |
.O (ddr_odt0) |
); |
|
//---- ******************************************* ---- |
//---- Includes the instantiation of FD and OBUF ---- |
//---- for addr signals ---- |
//---- ******************************************* ---- |
|
genvar addr_i; |
generate |
for(addr_i = 0; addr_i < `ROW_ADDRESS; addr_i = addr_i + 1) |
begin : gen_addr |
(* IOB = "FORCE" *) FD FD_inst |
( |
.Q (ddr_address_iob_reg[addr_i]), |
.D (ddr_address_cntrl[addr_i]), |
.C (~clk0) |
)/* synthesis syn_useioff = 1 */; |
|
OBUF OBUF_inst |
( |
.I (ddr_address_iob_reg[addr_i]), |
.O (ddr_address[addr_i]) |
); |
end |
endgenerate |
|
genvar ba_i; |
generate |
for(ba_i = 0; ba_i < `BANK_ADDRESS; ba_i = ba_i + 1) begin : gen_ba |
(* IOB = "FORCE" *) FD FD_inst |
( |
.Q (ddr_ba_reg[ba_i]), |
.D (ddr_ba_cntrl[ba_i]), |
.C (~clk0) |
)/* synthesis syn_useioff = 1 */; |
|
OBUF OBUF_inst |
( |
.I (ddr_ba_reg[ba_i]), |
.O (ddr_ba[ba_i]) |
); |
end |
endgenerate |
|
|
IBUF rst_iob_inbuf |
( |
.I (rst_dqs_div_in), |
.O (rst_dqs_div) |
); |
|
OBUF rst_iob_outbuf |
( |
.I (rst_dqs_div_int), |
.O (rst_dqs_div_out) |
); |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2.v
0,0 → 1,206
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007, 2008 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:42 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This module has the instantiations main and infrastructure_top |
// modules |
//***************************************************************************** |
|
`timescale 1ns/100ps |
|
(* X_CORE_INFO = "mig_v3_61_ddr2_sp3, Coregen 12.4" , |
CORE_GENERATION_INFO = "ddr2_sp3,mig_v3_61,{component_name=ddr2_sp3, data_width=32, memory_width=8, clk_width=2, bank_address=2, row_address=13, column_address=10, no_of_cs=1, cke_width=1, registered=0, data_mask=1, mask_enable=1, load_mode_register=13'b0010100110011, ext_load_mode_register=13'b0000000000000, language=Verilog, synthesis_tool=ISE, interface_type=DDR2_SDRAM, no_of_controllers=1}" *) |
module s3adsp_ddr2 |
( |
inout [31:0] cntrl0_ddr2_dq, |
output [12:0] cntrl0_ddr2_a, |
output [1:0] cntrl0_ddr2_ba, |
output cntrl0_ddr2_cke, |
output cntrl0_ddr2_cs_n, |
output cntrl0_ddr2_ras_n, |
output cntrl0_ddr2_cas_n, |
output cntrl0_ddr2_we_n, |
output cntrl0_ddr2_odt, |
output [3:0] cntrl0_ddr2_dm, |
input cntrl0_rst_dqs_div_in, |
output cntrl0_rst_dqs_div_out, |
input sys_clk_in, |
input reset_in_n, |
input cntrl0_burst_done, |
output cntrl0_init_done, |
output cntrl0_ar_done, |
output cntrl0_user_data_valid, |
output cntrl0_auto_ref_req, |
output cntrl0_user_cmd_ack, |
input [2:0] cntrl0_user_command_register, |
output cntrl0_clk_tb, |
output cntrl0_clk90_tb, |
output cntrl0_sys_rst_tb, |
output cntrl0_sys_rst90_tb, |
output cntrl0_sys_rst180_tb, |
input [7:0] cntrl0_user_data_mask, |
output [63:0] cntrl0_user_output_data, |
input [63:0] cntrl0_user_input_data, |
input [24:0] cntrl0_user_input_address, |
inout [3:0] cntrl0_ddr2_dqs, |
inout [3:0] cntrl0_ddr2_dqs_n, |
output [1:0] cntrl0_ddr2_ck, |
output [1:0] cntrl0_ddr2_ck_n |
); |
|
wire wait_200us; |
wire clk_0; |
wire clk90_0; |
wire sys_rst; |
wire sys_rst90; |
wire sys_rst180; |
wire [4:0] delay_sel_val; |
|
// debug signals declarations |
wire [4:0] dbg_delay_sel; |
wire [4:0] dbg_phase_cnt; |
wire [5:0] dbg_cnt; |
wire dbg_trans_onedtct; |
wire dbg_trans_twodtct; |
wire dbg_enb_trans_two_dtct; |
wire dbg_rst_calib; |
// chipscope signals |
wire [19:0] dbg_data; |
wire [3:0] dbg_trig; |
wire [35:0] control0; |
wire [35:0] control1; |
wire [11:0] vio_out; |
wire [4:0] vio_out_dqs; |
wire vio_out_dqs_en; |
wire [4:0] vio_out_rst_dqs_div; |
wire vio_out_rst_dqs_div_en; |
wire sys_clkb; |
wire sys_clk; |
|
assign sys_clkb = 1'b0; |
assign sys_clk = 1'b0; |
|
s3adsp_ddr2_top_0 top_00 |
( |
.ddr2_dq (cntrl0_ddr2_dq), |
.ddr2_a (cntrl0_ddr2_a), |
.ddr2_ba (cntrl0_ddr2_ba), |
.ddr2_cke (cntrl0_ddr2_cke), |
.ddr2_cs_n (cntrl0_ddr2_cs_n), |
.ddr2_ras_n (cntrl0_ddr2_ras_n), |
.ddr2_cas_n (cntrl0_ddr2_cas_n), |
.ddr2_we_n (cntrl0_ddr2_we_n), |
.ddr2_odt (cntrl0_ddr2_odt), |
.ddr2_dm (cntrl0_ddr2_dm), |
.rst_dqs_div_in (cntrl0_rst_dqs_div_in), |
.rst_dqs_div_out (cntrl0_rst_dqs_div_out), |
.burst_done (cntrl0_burst_done), |
.init_done (cntrl0_init_done), |
.ar_done (cntrl0_ar_done), |
.user_data_valid (cntrl0_user_data_valid), |
.auto_ref_req (cntrl0_auto_ref_req), |
.user_cmd_ack (cntrl0_user_cmd_ack), |
.user_command_register (cntrl0_user_command_register), |
.clk_tb (cntrl0_clk_tb), |
.clk90_tb (cntrl0_clk90_tb), |
.sys_rst_tb (cntrl0_sys_rst_tb), |
.sys_rst90_tb (cntrl0_sys_rst90_tb), |
.sys_rst180_tb (cntrl0_sys_rst180_tb), |
.user_data_mask (cntrl0_user_data_mask), |
.user_output_data (cntrl0_user_output_data), |
.user_input_data (cntrl0_user_input_data), |
.user_input_address (cntrl0_user_input_address), |
.ddr2_dqs (cntrl0_ddr2_dqs), |
.ddr2_dqs_n (cntrl0_ddr2_dqs_n), |
.ddr2_ck (cntrl0_ddr2_ck), |
.ddr2_ck_n (cntrl0_ddr2_ck_n), |
.wait_200us (wait_200us), |
.clk_int (clk_0), |
.clk90_int (clk90_0), |
.sys_rst (sys_rst), |
.sys_rst90 (sys_rst90), |
.sys_rst180 (sys_rst180), |
.delay_sel_val (delay_sel_val), |
|
//Debug signals |
|
.dbg_delay_sel (dbg_delay_sel), |
.dbg_rst_calib (dbg_rst_calib), |
.vio_out_dqs (vio_out_dqs), |
.vio_out_dqs_en (vio_out_dqs_en), |
.vio_out_rst_dqs_div (vio_out_rst_dqs_div), |
.vio_out_rst_dqs_div_en (vio_out_rst_dqs_div_en) |
); |
|
s3adsp_ddr2_infrastructure_top infrastructure_top0 |
( |
.sys_clkb (sys_clkb), |
.sys_clk (sys_clk), |
.sys_clk_in (sys_clk_in), |
.reset_in_n (reset_in_n), |
.wait_200us_rout (wait_200us), |
.delay_sel_val1_val (delay_sel_val), |
.sys_rst_val (sys_rst), |
.sys_rst90_val (sys_rst90), |
.clk_int_val (clk_0), |
.clk90_int_val (clk90_0), |
.sys_rst180_val (sys_rst180), |
.dbg_phase_cnt (dbg_phase_cnt), |
.dbg_cnt (dbg_cnt), |
.dbg_trans_onedtct (dbg_trans_onedtct), |
.dbg_trans_twodtct (dbg_trans_twodtct), |
.dbg_enb_trans_two_dtct (dbg_enb_trans_two_dtct) |
); |
|
|
|
endmodule |
|
|
|
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_infrastructure.v
0,0 → 1,89
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_infrastructure.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:41 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : |
//***************************************************************************** |
|
`timescale 1ns/100ps |
module s3adsp_ddr2_infrastructure |
( |
input clk_int, |
input rst_calib1, |
input [4:0] delay_sel_val, |
output [4:0] delay_sel_val1_val, |
// debug_signals |
output [4:0] dbg_delay_sel, |
output dbg_rst_calib |
); |
|
|
reg [4:0] delay_sel_val1; |
reg rst_calib1_r1; |
reg rst_calib1_r2; |
|
assign dbg_delay_sel = delay_sel_val1; |
assign dbg_rst_calib = rst_calib1_r2; |
|
assign delay_sel_val1_val = delay_sel_val1; |
|
always@(negedge clk_int) |
rst_calib1_r1 <= rst_calib1; |
|
always@(posedge clk_int) |
rst_calib1_r2 <= rst_calib1_r1; |
|
always@(posedge clk_int) begin |
if( rst_calib1_r2 == 1'b0 ) |
delay_sel_val1 <= delay_sel_val; |
else |
delay_sel_val1 <= delay_sel_val1; |
end |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_data_path_iobs_0.v
0,0 → 1,146
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007, 2008 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_data_path_iobs_0.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:41 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This module has the instantiations s3_dq_iob, s3_dqs_iob |
// and ddr_dm modules. |
//***************************************************************************** |
|
`timescale 1ns/100ps |
`include "s3adsp_ddr2_parameters_0.v" |
|
module s3adsp_ddr2_data_path_iobs_0 |
( |
input clk, |
input clk90, |
input dqs_reset, |
input dqs_enable, |
inout [(`DATA_STROBE_WIDTH-1):0] ddr_dqs, |
inout [(`DATA_WIDTH-1):0] ddr_dq, |
inout [(`DATA_STROBE_WIDTH-1):0] ddr_dqs_n, |
output [(`DATA_STROBE_WIDTH-1):0] dqs_int_delay_in, |
output [((`DATA_MASK_WIDTH)-1):0] ddr_dm, |
input [(`DATA_WIDTH-1):0] write_data_falling, |
input [(`DATA_WIDTH-1):0] write_data_rising, |
input write_en_val, |
input [(`DATA_MASK_WIDTH-1):0] data_mask_f, |
input [(`DATA_MASK_WIDTH-1):0] data_mask_r, |
output [(`DATA_WIDTH-1):0] ddr_dq_val |
); |
|
wire [(`DATA_WIDTH-1):0] ddr_dq_in; |
|
localparam MASK_CHK = `MASK_ENABLE; |
|
assign ddr_dq_val = ddr_dq_in; |
|
//*********************************************************************** |
// DM IOB instantiations |
//*********************************************************************** |
genvar mask_i; |
generate |
if(MASK_CHK == 1'd1) begin : MASK_INST |
for(mask_i = 0; mask_i < `DATA_MASK_WIDTH; mask_i = mask_i+1) begin: gen_dm |
s3adsp_ddr2_s3_dm_iob s3_dm_iob_inst |
( |
.ddr_dm (ddr_dm[mask_i]), |
.mask_falling (data_mask_f[mask_i]), |
.mask_rising (data_mask_r[mask_i]), |
.clk90 (clk90) |
); |
end |
end |
endgenerate |
|
|
//****************************************************************************** |
// Read Data Capture Module Instantiations |
//****************************************************************************** |
// DQS IOB instantiations |
//****************************************************************************** |
|
|
genvar dqs_i; |
generate |
for(dqs_i = 0; dqs_i < `DATA_STROBE_WIDTH; dqs_i = dqs_i+1) begin: gen_dqs |
s3adsp_ddr2_s3_dqs_iob s3_dqs_iob_inst |
( |
.clk (clk), |
.ddr_dqs_reset (dqs_reset), |
.ddr_dqs_enable (dqs_enable), |
.ddr_dqs (ddr_dqs[dqs_i]), |
.ddr_dqs_n (ddr_dqs_n[dqs_i]), |
.dqs (dqs_int_delay_in[dqs_i]) |
); |
end |
endgenerate |
|
|
|
|
//****************************************************************************** |
// DDR Data bit instantiations |
//****************************************************************************** |
|
genvar dq_i; |
generate |
for(dq_i = 0; dq_i < `DATA_WIDTH; dq_i = dq_i+1) begin: gen_dq |
s3adsp_ddr2_s3_dq_iob s3_dq_iob_inst |
( |
.ddr_dq_inout (ddr_dq[dq_i]), |
.write_data_falling (write_data_falling[dq_i]), |
.write_data_rising (write_data_rising[dq_i]), |
.read_data_in (ddr_dq_in[dq_i]), |
.clk90 (clk90), |
.write_en_val (write_en_val) |
); |
end |
endgenerate |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_cal_top.v
0,0 → 1,98
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_cal_top.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:41 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This module has the instantiations cal_ctl and tap_dly. |
//***************************************************************************** |
|
`timescale 1ns/100ps |
|
(* X_CORE_INFO = "mig_v3_61_ddr2_sp3, Coregen 12.4" , |
CORE_GENERATION_INFO = "ddr2_sp3,mig_v3_61,{component_name=ddr2_sp3, data_width=32, memory_width=8, clk_width=2, bank_address=2, row_address=13, column_address=10, no_of_cs=1, cke_width=1, registered=0, data_mask=1, mask_enable=1, load_mode_register=13'b0010100110011, ext_load_mode_register=13'b0000000000000, language=Verilog, synthesis_tool=ISE, interface_type=DDR2_SDRAM, no_of_controllers=1}" *) |
module s3adsp_ddr2_cal_top |
( |
input clk0, |
input clk0dcmlock, |
input reset, |
output [4:0] tapfordqs, |
// debug signals |
output [4:0] dbg_phase_cnt, |
output [5:0] dbg_cnt, |
output dbg_trans_onedtct, |
output dbg_trans_twodtct, |
output dbg_enb_trans_two_dtct |
); |
|
wire [31:0] flop2_val; |
wire fpga_rst; |
|
assign fpga_rst = (~reset || ~clk0dcmlock); |
|
s3adsp_ddr2_cal_ctl cal_ctl0 |
( |
.clk (clk0), |
.reset (fpga_rst), |
.flop2 (flop2_val), |
.tapfordqs (tapfordqs), |
.dbg_phase_cnt (dbg_phase_cnt), |
.dbg_cnt (dbg_cnt), |
.dbg_trans_onedtct (dbg_trans_onedtct), |
.dbg_trans_twodtct (dbg_trans_twodtct), |
.dbg_enb_trans_two_dtct (dbg_enb_trans_two_dtct) |
); |
|
s3adsp_ddr2_tap_dly tap_dly0 |
( |
.clk (clk0), |
.reset (fpga_rst), |
.tapin (clk0), |
.flop2 (flop2_val) |
); |
|
endmodule |
/s3adsp1800/rtl/verilog/xilinx_s3adsp_ddr2/s3adsp_ddr2_top_0.v
0,0 → 1,252
//***************************************************************************** |
// DISCLAIMER OF LIABILITY |
// |
// This file contains proprietary and confidential information of |
// Xilinx, Inc. ("Xilinx"), that is distributed under a license |
// from Xilinx, and may be used, copied and/or disclosed only |
// pursuant to the terms of a valid license agreement with Xilinx. |
// |
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
// does not warrant that functions included in the Materials will |
// meet the requirements of Licensee, or that the operation of the |
// Materials will be uninterrupted or error-free, or that defects |
// in the Materials will be corrected. Furthermore, Xilinx does |
// not warrant or make any representations regarding use, or the |
// results of the use, of the Materials in terms of correctness, |
// accuracy, reliability or otherwise. |
// |
// Xilinx products are not designed or intended to be fail-safe, |
// or for use in any application requiring fail-safe performance, |
// such as life-support or safety devices or systems, Class III |
// medical devices, nuclear facilities, applications related to |
// the deployment of airbags, or any other applications that could |
// lead to death, personal injury or severe property or |
// environmental damage (individually and collectively, "critical |
// applications"). Customer assumes the sole risk and liability |
// of any use of Xilinx products in critical applications, |
// subject only to applicable laws and regulations governing |
// limitations on product liability. |
// |
// Copyright 2005, 2006, 2007, 2008 Xilinx, Inc. |
// All rights reserved. |
// |
// This disclaimer and copyright notice must be retained as part |
// of this file at all times. |
//***************************************************************************** |
// ____ ____ |
// / /\/ / |
// /___/ \ / Vendor : Xilinx |
// \ \ \/ Version : 3.6.1 |
// \ \ Application : MIG |
// / / Filename : s3adsp_ddr2_top_0.v |
// /___/ /\ Date Last Modified : $Date: 2010/11/26 18:25:42 $ |
// \ \ / \ Date Created : Mon May 2 2005 |
// \___\/\___\ |
// Device : Spartan-3/3A/3A-DSP |
// Design Name : DDR2 SDRAM |
// Purpose : This modules has the instantiations infrastructure, iobs, |
// controller and data_paths modules |
//***************************************************************************** |
|
`timescale 1ns/100ps |
`include "s3adsp_ddr2_parameters_0.v" |
|
module s3adsp_ddr2_top_0 |
( |
input rst_dqs_div_in, |
output rst_dqs_div_out, |
input clk_int, |
input clk90_int, |
input [4:0] delay_sel_val, |
input sys_rst, |
input sys_rst90, |
input sys_rst180, |
input [((`DATA_WIDTH*2)-1):0] user_input_data, |
output [((`DATA_WIDTH*2)-1):0] user_output_data, |
output user_data_valid, |
input [((`ROW_ADDRESS + |
`COLUMN_ADDRESS + `BANK_ADDRESS)-1):0] user_input_address, |
input [2:0] user_command_register, |
output user_cmd_ack, |
input burst_done, |
output init_done, |
output ar_done, |
inout [((`DATA_STROBE_WIDTH)-1):0] ddr2_dqs, |
inout [(`DATA_WIDTH-1):0] ddr2_dq, |
output ddr2_cke, |
output ddr2_cs_n, |
output auto_ref_req, |
input wait_200us, |
output ddr2_ras_n, |
output ddr2_cas_n, |
output ddr2_we_n, |
output ddr2_odt, |
output [`BANK_ADDRESS-1:0] ddr2_ba, |
output [`ROW_ADDRESS-1:0] ddr2_a, |
output [(`CLK_WIDTH-1):0] ddr2_ck, |
input [((`DATA_MASK_WIDTH*2)-1):0] user_data_mask, |
output [((`DATA_MASK_WIDTH)-1):0] ddr2_dm, |
inout [(`DATA_STROBE_WIDTH-1):0] ddr2_dqs_n, |
|
output clk_tb, |
output clk90_tb, |
output sys_rst_tb, |
output sys_rst90_tb, |
output sys_rst180_tb, |
output [(`CLK_WIDTH-1):0] ddr2_ck_n, |
//debug_signals |
output [4:0] dbg_delay_sel, |
output dbg_rst_calib, |
input [4:0] vio_out_dqs, |
input vio_out_dqs_en, |
input [4:0] vio_out_rst_dqs_div, |
input vio_out_rst_dqs_div_en |
); |
|
|
wire rst_calib; |
wire [4:0] delay_sel; |
wire write_enable; |
wire dqs_div_rst; |
wire dqs_enable; |
wire dqs_reset; |
wire [(`DATA_WIDTH-1):0] dq; |
wire write_en_val; |
wire [((`DATA_MASK_WIDTH)-1):0] data_mask_f; |
wire [((`DATA_MASK_WIDTH)-1):0] data_mask_r; |
wire [(`DATA_WIDTH-1):0] write_data_falling; |
wire [(`DATA_WIDTH-1):0] write_data_rising; |
wire ddr_rasb_cntrl; |
wire ddr_casb_cntrl; |
wire ddr_web_cntrl; |
wire [`BANK_ADDRESS-1:0] ddr_ba_cntrl; |
wire [`ROW_ADDRESS-1:0] ddr_address_cntrl; |
wire ddr_cke_cntrl; |
wire ddr_csb_cntrl; |
wire ddr_odt_cntrl; |
wire rst_dqs_div_int; |
wire [(`DATA_STROBE_WIDTH-1):0] dqs_int_delay_in; |
|
assign clk_tb = clk_int; |
assign clk90_tb = clk90_int; |
assign sys_rst_tb = sys_rst; |
assign sys_rst90_tb = sys_rst90; |
assign sys_rst180_tb = sys_rst180; |
|
s3adsp_ddr2_controller_0 controller0 |
( |
.auto_ref_req (auto_ref_req), |
.wait_200us(wait_200us), |
.clk (clk_int), |
.rst0 (sys_rst), |
.rst180 (sys_rst180), |
.address (user_input_address[((`ROW_ADDRESS + |
`COLUMN_ADDRESS + |
`BANK_ADDRESS)-1): |
`BANK_ADDRESS]), |
.bank_address (user_input_address[(`BANK_ADDRESS-1): 0]), |
.command_register (user_command_register), |
.burst_done (burst_done), |
.ddr_rasb_cntrl (ddr_rasb_cntrl), |
.ddr_casb_cntrl (ddr_casb_cntrl), |
.ddr_web_cntrl (ddr_web_cntrl), |
.ddr_ba_cntrl (ddr_ba_cntrl), |
.ddr_address_cntrl (ddr_address_cntrl), |
.ddr_cke_cntrl (ddr_cke_cntrl), |
.ddr_csb_cntrl (ddr_csb_cntrl), |
.ddr_odt_cntrl (ddr_odt_cntrl), |
.dqs_enable (dqs_enable), |
.dqs_reset (dqs_reset), |
.write_enable (write_enable), |
.rst_calib (rst_calib), |
.rst_dqs_div_int (rst_dqs_div_int), |
.cmd_ack (user_cmd_ack), |
.init (init_done), |
.ar_done (ar_done), |
.read_fifo_rden (read_fifo_rden) // Added new signal |
); |
|
s3adsp_ddr2_data_path_0 data_path0 |
( |
.user_input_data (user_input_data), |
.user_data_mask (user_data_mask), |
.clk (clk_int), |
.clk90 (clk90_int), |
.reset (sys_rst), |
.reset90 (sys_rst90), |
.write_enable (write_enable), |
.rst_dqs_div_in (dqs_div_rst), |
.delay_sel (delay_sel), |
.dqs_int_delay_in (dqs_int_delay_in), |
.dq (dq), |
.u_data_val (user_data_valid), |
.user_output_data (user_output_data), |
.write_en_val (write_en_val), |
.data_mask_f (data_mask_f), |
.data_mask_r (data_mask_r), |
.write_data_falling (write_data_falling), |
.write_data_rising (write_data_rising), |
.read_fifo_rden (read_fifo_rden), // Added new signal |
//debug signals |
.vio_out_dqs (vio_out_dqs), |
.vio_out_dqs_en (vio_out_dqs_en), |
.vio_out_rst_dqs_div (vio_out_rst_dqs_div), |
.vio_out_rst_dqs_div_en (vio_out_rst_dqs_div_en) |
); |
|
s3adsp_ddr2_infrastructure infrastructure0 |
( |
.clk_int (clk_int), |
.rst_calib1 (rst_calib), |
.delay_sel_val (delay_sel_val), |
.delay_sel_val1_val (delay_sel), |
.dbg_delay_sel (dbg_delay_sel), |
.dbg_rst_calib (dbg_rst_calib) |
); |
|
s3adsp_ddr2_iobs_0 iobs0 |
( |
.clk (clk_int), |
.clk90 (clk90_int), |
.ddr_rasb_cntrl (ddr_rasb_cntrl), |
.ddr_casb_cntrl (ddr_casb_cntrl), |
.ddr_web_cntrl (ddr_web_cntrl), |
.ddr_cke_cntrl (ddr_cke_cntrl), |
.ddr_csb_cntrl (ddr_csb_cntrl), |
.ddr_odt_cntrl (ddr_odt_cntrl), |
.ddr_address_cntrl (ddr_address_cntrl), |
.ddr_ba_cntrl (ddr_ba_cntrl), |
.rst_dqs_div_int (rst_dqs_div_int), |
.dqs_reset (dqs_reset), |
.dqs_enable (dqs_enable), |
.ddr_dqs (ddr2_dqs), |
.ddr_dqs_n (ddr2_dqs_n), |
.ddr_dq (ddr2_dq), |
.write_data_falling(write_data_falling), |
.write_data_rising (write_data_rising), |
.write_en_val (write_en_val), |
.data_mask_f (data_mask_f), |
.data_mask_r (data_mask_r), |
.ddr2_ck (ddr2_ck), |
.ddr2_ck_n (ddr2_ck_n), |
.ddr_rasb (ddr2_ras_n), |
.ddr_casb (ddr2_cas_n), |
.ddr_web (ddr2_we_n), |
.ddr_ba (ddr2_ba), |
.ddr_address (ddr2_a), |
.ddr_cke (ddr2_cke), |
.ddr_csb (ddr2_cs_n), |
.ddr_odt0 (ddr2_odt), |
.rst_dqs_div (dqs_div_rst), |
.rst_dqs_div_in (rst_dqs_div_in), |
.rst_dqs_div_out (rst_dqs_div_out), |
.dqs_int_delay_in (dqs_int_delay_in), |
.ddr_dm (ddr2_dm), |
.dq (dq) |
); |
|
endmodule |
/s3adsp1800/rtl/verilog/orpsoc_top/orpsoc_top.v
0,0 → 1,1479
////////////////////////////////////////////////////////////////////// |
/// //// |
/// ORPSoC top for Spartan 3A DSP 1800 Board //// |
/// //// |
/// Instantiates modules, depending on ORPSoC defines file //// |
/// //// |
/// Julius Baxter, julius@opencores.org //// |
/// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009,2010,2011 Authors and 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
`include "orpsoc-defines.v" |
`include "synthesis-defines.v" |
module orpsoc_top |
( |
`ifdef JTAG_DEBUG |
tdo_pad_o, tms_pad_i, tck_pad_i, tdi_pad_i, |
`endif |
`ifdef XILINX_DDR2 |
ddr2_dq, ddr2_a, ddr2_ba, ddr2_cke, ddr2_cs_n, ddr2_ras_n, ddr2_cas_n, |
ddr2_we_n, ddr2_odt, ddr2_dm, ddr2_dqs, ddr2_dqs_n, ddr2_ck, |
ddr2_ck_n, ddr2_rst_dqs_div_in, ddr2_rst_dqs_div_out, |
`endif |
`ifdef UART0 |
uart0_srx_pad_i, uart0_stx_pad_o, |
uart0_srx_expheader_pad_i, uart0_stx_expheader_pad_o, |
`endif |
`ifdef SPI0 |
spi0_mosi_o, spi0_ss_o, spi0_sck_o, spi0_miso_i, |
`endif |
`ifdef I2C0 |
i2c0_sda_io, i2c0_scl_io, |
`endif |
`ifdef GPIO0 |
gpio0_io, |
`endif |
|
`ifdef ETH0 |
eth0_tx_clk, eth0_tx_data, eth0_tx_en, eth0_tx_er, |
eth0_rx_clk, eth0_rx_data, eth0_dv, eth0_rx_er, |
eth0_col, eth0_crs, |
eth0_mdc_pad_o, eth0_md_pad_io, |
`ifdef ETH0_PHY_RST |
eth0_rst_n_o, |
`endif |
`endif |
|
sys_clk_i, |
|
rst_n_pad_i |
|
); |
|
`include "orpsoc-params.v" |
|
input sys_clk_i; |
|
input rst_n_pad_i; |
|
`ifdef JTAG_DEBUG |
output tdo_pad_o; |
input tms_pad_i; |
input tck_pad_i; |
input tdi_pad_i; |
`endif |
`ifdef XILINX_DDR2 |
inout [31:0] ddr2_dq; |
output [12:0] ddr2_a; |
output [1:0] ddr2_ba; |
output ddr2_cke; |
output ddr2_cs_n; |
output ddr2_ras_n; |
output ddr2_cas_n; |
output ddr2_we_n; |
output ddr2_odt; |
output [3:0] ddr2_dm; |
inout [3:0] ddr2_dqs; |
inout [3:0] ddr2_dqs_n; |
output [1:0] ddr2_ck; |
output [1:0] ddr2_ck_n; |
input ddr2_rst_dqs_div_in; |
output ddr2_rst_dqs_div_out; |
`endif |
|
`ifdef UART0 |
input uart0_srx_pad_i; |
output uart0_stx_pad_o; |
// Duplicates of the UART signals, this time to the USB debug cable |
input uart0_srx_expheader_pad_i; |
output uart0_stx_expheader_pad_o; |
`endif |
`ifdef SPI0 |
output spi0_mosi_o; |
output [spi0_ss_width-1:0] spi0_ss_o; |
output spi0_sck_o; |
input spi0_miso_i; |
`endif |
`ifdef I2C0 |
inout i2c0_sda_io, i2c0_scl_io; |
`endif |
|
`ifdef GPIO0 |
inout [gpio0_io_width-1:0] gpio0_io; |
`endif |
`ifdef ETH0 |
input eth0_tx_clk; |
output [3:0] eth0_tx_data; |
output eth0_tx_en; |
output eth0_tx_er; |
input eth0_rx_clk; |
input [3:0] eth0_rx_data; |
input eth0_dv; |
input eth0_rx_er; |
input eth0_col; |
input eth0_crs; |
output eth0_mdc_pad_o; |
inout eth0_md_pad_io; |
`ifdef ETH0_PHY_RST |
output eth0_rst_n_o; |
`endif |
`endif // `ifdef ETH0 |
|
//////////////////////////////////////////////////////////////////////// |
// |
// Clock and reset generation module |
// |
//////////////////////////////////////////////////////////////////////// |
|
// |
// Wires |
// |
wire wb_clk, wb_rst; |
wire clk133; |
wire dbg_tck; |
|
|
clkgen clkgen0 |
( |
.sys_clk_i (sys_clk_i), |
|
.wb_clk_o (wb_clk), |
.wb_rst_o (wb_rst), |
|
`ifdef JTAG_DEBUG |
.tck_pad_i (tck_pad_i), |
.dbg_tck_o (dbg_tck), |
`endif |
`ifdef XILINX_DDR2 |
.clk133_o (clk133), |
`endif |
|
// Asynchronous active low reset |
.rst_n_pad_i (rst_n_pad_i) |
); |
|
|
//////////////////////////////////////////////////////////////////////// |
// |
// Arbiter |
// |
//////////////////////////////////////////////////////////////////////// |
|
// Wire naming convention: |
// First: wishbone master or slave (wbm/wbs) |
// Second: Which bus it's on instruction or data (i/d) |
// Third: Between which module and the arbiter the wires are |
// Fourth: Signal name |
// Fifth: Direction relative to module (not bus/arbiter!) |
// ie. wbm_d_or12_adr_o is address OUT from the or1200 |
|
// OR1200 instruction bus wires |
wire [wb_aw-1:0] wbm_i_or12_adr_o; |
wire [wb_dw-1:0] wbm_i_or12_dat_o; |
wire [3:0] wbm_i_or12_sel_o; |
wire wbm_i_or12_we_o; |
wire wbm_i_or12_cyc_o; |
wire wbm_i_or12_stb_o; |
wire [2:0] wbm_i_or12_cti_o; |
wire [1:0] wbm_i_or12_bte_o; |
|
wire [wb_dw-1:0] wbm_i_or12_dat_i; |
wire wbm_i_or12_ack_i; |
wire wbm_i_or12_err_i; |
wire wbm_i_or12_rty_i; |
|
// OR1200 data bus wires |
wire [wb_aw-1:0] wbm_d_or12_adr_o; |
wire [wb_dw-1:0] wbm_d_or12_dat_o; |
wire [3:0] wbm_d_or12_sel_o; |
wire wbm_d_or12_we_o; |
wire wbm_d_or12_cyc_o; |
wire wbm_d_or12_stb_o; |
wire [2:0] wbm_d_or12_cti_o; |
wire [1:0] wbm_d_or12_bte_o; |
|
wire [wb_dw-1:0] wbm_d_or12_dat_i; |
wire wbm_d_or12_ack_i; |
wire wbm_d_or12_err_i; |
wire wbm_d_or12_rty_i; |
|
// Debug interface bus wires |
wire [wb_aw-1:0] wbm_d_dbg_adr_o; |
wire [wb_dw-1:0] wbm_d_dbg_dat_o; |
wire [3:0] wbm_d_dbg_sel_o; |
wire wbm_d_dbg_we_o; |
wire wbm_d_dbg_cyc_o; |
wire wbm_d_dbg_stb_o; |
wire [2:0] wbm_d_dbg_cti_o; |
wire [1:0] wbm_d_dbg_bte_o; |
|
wire [wb_dw-1:0] wbm_d_dbg_dat_i; |
wire wbm_d_dbg_ack_i; |
wire wbm_d_dbg_err_i; |
wire wbm_d_dbg_rty_i; |
|
// Byte bus bridge master signals |
wire [wb_aw-1:0] wbm_b_d_adr_o; |
wire [wb_dw-1:0] wbm_b_d_dat_o; |
wire [3:0] wbm_b_d_sel_o; |
wire wbm_b_d_we_o; |
wire wbm_b_d_cyc_o; |
wire wbm_b_d_stb_o; |
wire [2:0] wbm_b_d_cti_o; |
wire [1:0] wbm_b_d_bte_o; |
|
wire [wb_dw-1:0] wbm_b_d_dat_i; |
wire wbm_b_d_ack_i; |
wire wbm_b_d_err_i; |
wire wbm_b_d_rty_i; |
|
// Instruction bus slave wires // |
|
// rom0 instruction bus wires |
wire [31:0] wbs_i_rom0_adr_i; |
wire [wbs_i_rom0_data_width-1:0] wbs_i_rom0_dat_i; |
wire [3:0] wbs_i_rom0_sel_i; |
wire wbs_i_rom0_we_i; |
wire wbs_i_rom0_cyc_i; |
wire wbs_i_rom0_stb_i; |
wire [2:0] wbs_i_rom0_cti_i; |
wire [1:0] wbs_i_rom0_bte_i; |
wire [wbs_i_rom0_data_width-1:0] wbs_i_rom0_dat_o; |
wire wbs_i_rom0_ack_o; |
wire wbs_i_rom0_err_o; |
wire wbs_i_rom0_rty_o; |
|
// mc0 instruction bus wires |
wire [31:0] wbs_i_mc0_adr_i; |
wire [wbs_i_mc0_data_width-1:0] wbs_i_mc0_dat_i; |
wire [3:0] wbs_i_mc0_sel_i; |
wire wbs_i_mc0_we_i; |
wire wbs_i_mc0_cyc_i; |
wire wbs_i_mc0_stb_i; |
wire [2:0] wbs_i_mc0_cti_i; |
wire [1:0] wbs_i_mc0_bte_i; |
wire [wbs_i_mc0_data_width-1:0] wbs_i_mc0_dat_o; |
wire wbs_i_mc0_ack_o; |
wire wbs_i_mc0_err_o; |
wire wbs_i_mc0_rty_o; |
|
// Data bus slave wires // |
|
// mc0 data bus wires |
wire [31:0] wbs_d_mc0_adr_i; |
wire [wbs_d_mc0_data_width-1:0] wbs_d_mc0_dat_i; |
wire [3:0] wbs_d_mc0_sel_i; |
wire wbs_d_mc0_we_i; |
wire wbs_d_mc0_cyc_i; |
wire wbs_d_mc0_stb_i; |
wire [2:0] wbs_d_mc0_cti_i; |
wire [1:0] wbs_d_mc0_bte_i; |
wire [wbs_d_mc0_data_width-1:0] wbs_d_mc0_dat_o; |
wire wbs_d_mc0_ack_o; |
wire wbs_d_mc0_err_o; |
wire wbs_d_mc0_rty_o; |
|
// i2c0 wires |
wire [31:0] wbs_d_i2c0_adr_i; |
wire [wbs_d_i2c0_data_width-1:0] wbs_d_i2c0_dat_i; |
wire [3:0] wbs_d_i2c0_sel_i; |
wire wbs_d_i2c0_we_i; |
wire wbs_d_i2c0_cyc_i; |
wire wbs_d_i2c0_stb_i; |
wire [2:0] wbs_d_i2c0_cti_i; |
wire [1:0] wbs_d_i2c0_bte_i; |
wire [wbs_d_i2c0_data_width-1:0] wbs_d_i2c0_dat_o; |
wire wbs_d_i2c0_ack_o; |
wire wbs_d_i2c0_err_o; |
wire wbs_d_i2c0_rty_o; |
|
// i2c1 wires |
wire [31:0] wbs_d_i2c1_adr_i; |
wire [wbs_d_i2c1_data_width-1:0] wbs_d_i2c1_dat_i; |
wire [3:0] wbs_d_i2c1_sel_i; |
wire wbs_d_i2c1_we_i; |
wire wbs_d_i2c1_cyc_i; |
wire wbs_d_i2c1_stb_i; |
wire [2:0] wbs_d_i2c1_cti_i; |
wire [1:0] wbs_d_i2c1_bte_i; |
wire [wbs_d_i2c1_data_width-1:0] wbs_d_i2c1_dat_o; |
wire wbs_d_i2c1_ack_o; |
wire wbs_d_i2c1_err_o; |
wire wbs_d_i2c1_rty_o; |
|
// spi0 wires |
wire [31:0] wbs_d_spi0_adr_i; |
wire [wbs_d_spi0_data_width-1:0] wbs_d_spi0_dat_i; |
wire [3:0] wbs_d_spi0_sel_i; |
wire wbs_d_spi0_we_i; |
wire wbs_d_spi0_cyc_i; |
wire wbs_d_spi0_stb_i; |
wire [2:0] wbs_d_spi0_cti_i; |
wire [1:0] wbs_d_spi0_bte_i; |
wire [wbs_d_spi0_data_width-1:0] wbs_d_spi0_dat_o; |
wire wbs_d_spi0_ack_o; |
wire wbs_d_spi0_err_o; |
wire wbs_d_spi0_rty_o; |
|
// uart0 wires |
wire [31:0] wbs_d_uart0_adr_i; |
wire [wbs_d_uart0_data_width-1:0] wbs_d_uart0_dat_i; |
wire [3:0] wbs_d_uart0_sel_i; |
wire wbs_d_uart0_we_i; |
wire wbs_d_uart0_cyc_i; |
wire wbs_d_uart0_stb_i; |
wire [2:0] wbs_d_uart0_cti_i; |
wire [1:0] wbs_d_uart0_bte_i; |
wire [wbs_d_uart0_data_width-1:0] wbs_d_uart0_dat_o; |
wire wbs_d_uart0_ack_o; |
wire wbs_d_uart0_err_o; |
wire wbs_d_uart0_rty_o; |
|
// gpio0 wires |
wire [31:0] wbs_d_gpio0_adr_i; |
wire [wbs_d_gpio0_data_width-1:0] wbs_d_gpio0_dat_i; |
wire [3:0] wbs_d_gpio0_sel_i; |
wire wbs_d_gpio0_we_i; |
wire wbs_d_gpio0_cyc_i; |
wire wbs_d_gpio0_stb_i; |
wire [2:0] wbs_d_gpio0_cti_i; |
wire [1:0] wbs_d_gpio0_bte_i; |
wire [wbs_d_gpio0_data_width-1:0] wbs_d_gpio0_dat_o; |
wire wbs_d_gpio0_ack_o; |
wire wbs_d_gpio0_err_o; |
wire wbs_d_gpio0_rty_o; |
|
// eth0 slave wires |
wire [31:0] wbs_d_eth0_adr_i; |
wire [wbs_d_eth0_data_width-1:0] wbs_d_eth0_dat_i; |
wire [3:0] wbs_d_eth0_sel_i; |
wire wbs_d_eth0_we_i; |
wire wbs_d_eth0_cyc_i; |
wire wbs_d_eth0_stb_i; |
wire [2:0] wbs_d_eth0_cti_i; |
wire [1:0] wbs_d_eth0_bte_i; |
wire [wbs_d_eth0_data_width-1:0] wbs_d_eth0_dat_o; |
wire wbs_d_eth0_ack_o; |
wire wbs_d_eth0_err_o; |
wire wbs_d_eth0_rty_o; |
|
// eth0 master wires |
wire [wbm_eth0_addr_width-1:0] wbm_eth0_adr_o; |
wire [wbm_eth0_data_width-1:0] wbm_eth0_dat_o; |
wire [3:0] wbm_eth0_sel_o; |
wire wbm_eth0_we_o; |
wire wbm_eth0_cyc_o; |
wire wbm_eth0_stb_o; |
wire [2:0] wbm_eth0_cti_o; |
wire [1:0] wbm_eth0_bte_o; |
wire [wbm_eth0_data_width-1:0] wbm_eth0_dat_i; |
wire wbm_eth0_ack_i; |
wire wbm_eth0_err_i; |
wire wbm_eth0_rty_i; |
|
|
|
// |
// Wishbone instruction bus arbiter |
// |
|
arbiter_ibus arbiter_ibus0 |
( |
// Instruction Bus Master |
// Inputs to arbiter from master |
.wbm_adr_o (wbm_i_or12_adr_o), |
.wbm_dat_o (wbm_i_or12_dat_o), |
.wbm_sel_o (wbm_i_or12_sel_o), |
.wbm_we_o (wbm_i_or12_we_o), |
.wbm_cyc_o (wbm_i_or12_cyc_o), |
.wbm_stb_o (wbm_i_or12_stb_o), |
.wbm_cti_o (wbm_i_or12_cti_o), |
.wbm_bte_o (wbm_i_or12_bte_o), |
// Outputs to master from arbiter |
.wbm_dat_i (wbm_i_or12_dat_i), |
.wbm_ack_i (wbm_i_or12_ack_i), |
.wbm_err_i (wbm_i_or12_err_i), |
.wbm_rty_i (wbm_i_or12_rty_i), |
|
// Slave 0 |
// Inputs to slave from arbiter |
.wbs0_adr_i (wbs_i_rom0_adr_i), |
.wbs0_dat_i (wbs_i_rom0_dat_i), |
.wbs0_sel_i (wbs_i_rom0_sel_i), |
.wbs0_we_i (wbs_i_rom0_we_i), |
.wbs0_cyc_i (wbs_i_rom0_cyc_i), |
.wbs0_stb_i (wbs_i_rom0_stb_i), |
.wbs0_cti_i (wbs_i_rom0_cti_i), |
.wbs0_bte_i (wbs_i_rom0_bte_i), |
// Outputs from slave to arbiter |
.wbs0_dat_o (wbs_i_rom0_dat_o), |
.wbs0_ack_o (wbs_i_rom0_ack_o), |
.wbs0_err_o (wbs_i_rom0_err_o), |
.wbs0_rty_o (wbs_i_rom0_rty_o), |
|
// Slave 1 |
// Inputs to slave from arbiter |
.wbs1_adr_i (wbs_i_mc0_adr_i), |
.wbs1_dat_i (wbs_i_mc0_dat_i), |
.wbs1_sel_i (wbs_i_mc0_sel_i), |
.wbs1_we_i (wbs_i_mc0_we_i), |
.wbs1_cyc_i (wbs_i_mc0_cyc_i), |
.wbs1_stb_i (wbs_i_mc0_stb_i), |
.wbs1_cti_i (wbs_i_mc0_cti_i), |
.wbs1_bte_i (wbs_i_mc0_bte_i), |
// Outputs from slave to arbiter |
.wbs1_dat_o (wbs_i_mc0_dat_o), |
.wbs1_ack_o (wbs_i_mc0_ack_o), |
.wbs1_err_o (wbs_i_mc0_err_o), |
.wbs1_rty_o (wbs_i_mc0_rty_o), |
|
// Clock, reset inputs |
.wb_clk (wb_clk), |
.wb_rst (wb_rst)); |
|
defparam arbiter_ibus0.wb_addr_match_width = ibus_arb_addr_match_width; |
|
defparam arbiter_ibus0.slave0_adr = ibus_arb_slave0_adr; // FLASH ROM |
defparam arbiter_ibus0.slave1_adr = ibus_arb_slave1_adr; // Main memory |
|
// |
// Wishbone data bus arbiter |
// |
|
arbiter_dbus arbiter_dbus0 |
( |
// Master 0 |
// Inputs to arbiter from master |
.wbm0_adr_o (wbm_d_or12_adr_o), |
.wbm0_dat_o (wbm_d_or12_dat_o), |
.wbm0_sel_o (wbm_d_or12_sel_o), |
.wbm0_we_o (wbm_d_or12_we_o), |
.wbm0_cyc_o (wbm_d_or12_cyc_o), |
.wbm0_stb_o (wbm_d_or12_stb_o), |
.wbm0_cti_o (wbm_d_or12_cti_o), |
.wbm0_bte_o (wbm_d_or12_bte_o), |
// Outputs to master from arbiter |
.wbm0_dat_i (wbm_d_or12_dat_i), |
.wbm0_ack_i (wbm_d_or12_ack_i), |
.wbm0_err_i (wbm_d_or12_err_i), |
.wbm0_rty_i (wbm_d_or12_rty_i), |
|
// Master 0 |
// Inputs to arbiter from master |
.wbm1_adr_o (wbm_d_dbg_adr_o), |
.wbm1_dat_o (wbm_d_dbg_dat_o), |
.wbm1_we_o (wbm_d_dbg_we_o), |
.wbm1_cyc_o (wbm_d_dbg_cyc_o), |
.wbm1_sel_o (wbm_d_dbg_sel_o), |
.wbm1_stb_o (wbm_d_dbg_stb_o), |
.wbm1_cti_o (wbm_d_dbg_cti_o), |
.wbm1_bte_o (wbm_d_dbg_bte_o), |
// Outputs to master from arbiter |
.wbm1_dat_i (wbm_d_dbg_dat_i), |
.wbm1_ack_i (wbm_d_dbg_ack_i), |
.wbm1_err_i (wbm_d_dbg_err_i), |
.wbm1_rty_i (wbm_d_dbg_rty_i), |
|
// Slaves |
|
.wbs0_adr_i (wbs_d_mc0_adr_i), |
.wbs0_dat_i (wbs_d_mc0_dat_i), |
.wbs0_sel_i (wbs_d_mc0_sel_i), |
.wbs0_we_i (wbs_d_mc0_we_i), |
.wbs0_cyc_i (wbs_d_mc0_cyc_i), |
.wbs0_stb_i (wbs_d_mc0_stb_i), |
.wbs0_cti_i (wbs_d_mc0_cti_i), |
.wbs0_bte_i (wbs_d_mc0_bte_i), |
.wbs0_dat_o (wbs_d_mc0_dat_o), |
.wbs0_ack_o (wbs_d_mc0_ack_o), |
.wbs0_err_o (wbs_d_mc0_err_o), |
.wbs0_rty_o (wbs_d_mc0_rty_o), |
|
.wbs1_adr_i (wbs_d_eth0_adr_i), |
.wbs1_dat_i (wbs_d_eth0_dat_i), |
.wbs1_sel_i (wbs_d_eth0_sel_i), |
.wbs1_we_i (wbs_d_eth0_we_i), |
.wbs1_cyc_i (wbs_d_eth0_cyc_i), |
.wbs1_stb_i (wbs_d_eth0_stb_i), |
.wbs1_cti_i (wbs_d_eth0_cti_i), |
.wbs1_bte_i (wbs_d_eth0_bte_i), |
.wbs1_dat_o (wbs_d_eth0_dat_o), |
.wbs1_ack_o (wbs_d_eth0_ack_o), |
.wbs1_err_o (wbs_d_eth0_err_o), |
.wbs1_rty_o (wbs_d_eth0_rty_o), |
|
.wbs2_adr_i (wbm_b_d_adr_o), |
.wbs2_dat_i (wbm_b_d_dat_o), |
.wbs2_sel_i (wbm_b_d_sel_o), |
.wbs2_we_i (wbm_b_d_we_o), |
.wbs2_cyc_i (wbm_b_d_cyc_o), |
.wbs2_stb_i (wbm_b_d_stb_o), |
.wbs2_cti_i (wbm_b_d_cti_o), |
.wbs2_bte_i (wbm_b_d_bte_o), |
.wbs2_dat_o (wbm_b_d_dat_i), |
.wbs2_ack_o (wbm_b_d_ack_i), |
.wbs2_err_o (wbm_b_d_err_i), |
.wbs2_rty_o (wbm_b_d_rty_i), |
|
// Clock, reset inputs |
.wb_clk (wb_clk), |
.wb_rst (wb_rst)); |
|
// These settings are from top level params file |
defparam arbiter_dbus0.wb_addr_match_width = dbus_arb_wb_addr_match_width; |
defparam arbiter_dbus0.wb_num_slaves = dbus_arb_wb_num_slaves; |
defparam arbiter_dbus0.slave0_adr = dbus_arb_slave0_adr; |
defparam arbiter_dbus0.slave1_adr = dbus_arb_slave1_adr; |
|
// |
// Wishbone byte-wide bus arbiter |
// |
|
arbiter_bytebus arbiter_bytebus0 |
( |
|
// Master 0 |
// Inputs to arbiter from master |
.wbm0_adr_o (wbm_b_d_adr_o), |
.wbm0_dat_o (wbm_b_d_dat_o), |
.wbm0_sel_o (wbm_b_d_sel_o), |
.wbm0_we_o (wbm_b_d_we_o), |
.wbm0_cyc_o (wbm_b_d_cyc_o), |
.wbm0_stb_o (wbm_b_d_stb_o), |
.wbm0_cti_o (wbm_b_d_cti_o), |
.wbm0_bte_o (wbm_b_d_bte_o), |
// Outputs to master from arbiter |
.wbm0_dat_i (wbm_b_d_dat_i), |
.wbm0_ack_i (wbm_b_d_ack_i), |
.wbm0_err_i (wbm_b_d_err_i), |
.wbm0_rty_i (wbm_b_d_rty_i), |
|
// Byte bus slaves |
|
.wbs0_adr_i (wbs_d_uart0_adr_i), |
.wbs0_dat_i (wbs_d_uart0_dat_i), |
.wbs0_we_i (wbs_d_uart0_we_i), |
.wbs0_cyc_i (wbs_d_uart0_cyc_i), |
.wbs0_stb_i (wbs_d_uart0_stb_i), |
.wbs0_cti_i (wbs_d_uart0_cti_i), |
.wbs0_bte_i (wbs_d_uart0_bte_i), |
.wbs0_dat_o (wbs_d_uart0_dat_o), |
.wbs0_ack_o (wbs_d_uart0_ack_o), |
.wbs0_err_o (wbs_d_uart0_err_o), |
.wbs0_rty_o (wbs_d_uart0_rty_o), |
|
.wbs1_adr_i (wbs_d_gpio0_adr_i), |
.wbs1_dat_i (wbs_d_gpio0_dat_i), |
.wbs1_we_i (wbs_d_gpio0_we_i), |
.wbs1_cyc_i (wbs_d_gpio0_cyc_i), |
.wbs1_stb_i (wbs_d_gpio0_stb_i), |
.wbs1_cti_i (wbs_d_gpio0_cti_i), |
.wbs1_bte_i (wbs_d_gpio0_bte_i), |
.wbs1_dat_o (wbs_d_gpio0_dat_o), |
.wbs1_ack_o (wbs_d_gpio0_ack_o), |
.wbs1_err_o (wbs_d_gpio0_err_o), |
.wbs1_rty_o (wbs_d_gpio0_rty_o), |
|
.wbs2_adr_i (wbs_d_i2c0_adr_i), |
.wbs2_dat_i (wbs_d_i2c0_dat_i), |
.wbs2_we_i (wbs_d_i2c0_we_i), |
.wbs2_cyc_i (wbs_d_i2c0_cyc_i), |
.wbs2_stb_i (wbs_d_i2c0_stb_i), |
.wbs2_cti_i (wbs_d_i2c0_cti_i), |
.wbs2_bte_i (wbs_d_i2c0_bte_i), |
.wbs2_dat_o (wbs_d_i2c0_dat_o), |
.wbs2_ack_o (wbs_d_i2c0_ack_o), |
.wbs2_err_o (wbs_d_i2c0_err_o), |
.wbs2_rty_o (wbs_d_i2c0_rty_o), |
|
.wbs3_adr_i (), |
.wbs3_dat_i (), |
.wbs3_we_i (), |
.wbs3_cyc_i (), |
.wbs3_stb_i (), |
.wbs3_cti_i (), |
.wbs3_bte_i (), |
.wbs3_dat_o (32'd0), |
.wbs3_ack_o (1'b0), |
.wbs3_err_o (1'b0), |
.wbs3_rty_o (1'b0), |
|
.wbs4_adr_i (wbs_d_spi0_adr_i), |
.wbs4_dat_i (wbs_d_spi0_dat_i), |
.wbs4_we_i (wbs_d_spi0_we_i), |
.wbs4_cyc_i (wbs_d_spi0_cyc_i), |
.wbs4_stb_i (wbs_d_spi0_stb_i), |
.wbs4_cti_i (wbs_d_spi0_cti_i), |
.wbs4_bte_i (wbs_d_spi0_bte_i), |
.wbs4_dat_o (wbs_d_spi0_dat_o), |
.wbs4_ack_o (wbs_d_spi0_ack_o), |
.wbs4_err_o (wbs_d_spi0_err_o), |
.wbs4_rty_o (wbs_d_spi0_rty_o), |
|
// Clock, reset inputs |
.wb_clk (wb_clk), |
.wb_rst (wb_rst)); |
|
defparam arbiter_bytebus0.wb_addr_match_width = bbus_arb_wb_addr_match_width; |
defparam arbiter_bytebus0.wb_num_slaves = bbus_arb_wb_num_slaves; |
|
defparam arbiter_bytebus0.slave0_adr = bbus_arb_slave0_adr; |
defparam arbiter_bytebus0.slave1_adr = bbus_arb_slave1_adr; |
defparam arbiter_bytebus0.slave2_adr = bbus_arb_slave2_adr; |
defparam arbiter_bytebus0.slave3_adr = bbus_arb_slave3_adr; |
defparam arbiter_bytebus0.slave4_adr = bbus_arb_slave4_adr; |
|
|
`ifdef JTAG_DEBUG |
//////////////////////////////////////////////////////////////////////// |
// |
// JTAG TAP |
// |
//////////////////////////////////////////////////////////////////////// |
|
// |
// Wires |
// |
wire dbg_if_select; |
wire dbg_if_tdo; |
wire jtag_tap_tdo; |
wire jtag_tap_shift_dr, jtag_tap_pause_dr, |
jtag_tap_upate_dr, jtag_tap_capture_dr; |
// |
// Instantiation |
// |
|
jtag_tap jtag_tap0 |
( |
// Ports to pads |
.tdo_pad_o (tdo_pad_o), |
.tms_pad_i (tms_pad_i), |
.tck_pad_i (dbg_tck), |
.trst_pad_i (async_rst), |
.tdi_pad_i (tdi_pad_i), |
|
.tdo_padoe_o (tdo_padoe_o), |
|
.tdo_o (jtag_tap_tdo), |
|
.shift_dr_o (jtag_tap_shift_dr), |
.pause_dr_o (jtag_tap_pause_dr), |
.update_dr_o (jtag_tap_update_dr), |
.capture_dr_o (jtag_tap_capture_dr), |
|
.extest_select_o (), |
.sample_preload_select_o (), |
.mbist_select_o (), |
.debug_select_o (dbg_if_select), |
|
|
.bs_chain_tdi_i (1'b0), |
.mbist_tdi_i (1'b0), |
.debug_tdi_i (dbg_if_tdo) |
|
); |
|
//////////////////////////////////////////////////////////////////////// |
`endif // `ifdef JTAG_DEBUG |
|
//////////////////////////////////////////////////////////////////////// |
// |
// OpenRISC processor |
// |
//////////////////////////////////////////////////////////////////////// |
|
// |
// Wires |
// |
|
wire [30:0] or1200_pic_ints; |
|
wire [31:0] or1200_dbg_dat_i; |
wire [31:0] or1200_dbg_adr_i; |
wire or1200_dbg_we_i; |
wire or1200_dbg_stb_i; |
wire or1200_dbg_ack_o; |
wire [31:0] or1200_dbg_dat_o; |
|
wire or1200_dbg_stall_i; |
wire or1200_dbg_ewt_i; |
wire [3:0] or1200_dbg_lss_o; |
wire [1:0] or1200_dbg_is_o; |
wire [10:0] or1200_dbg_wp_o; |
wire or1200_dbg_bp_o; |
wire or1200_dbg_rst; |
|
wire or1200_clk, or1200_rst; |
wire sig_tick; |
|
// |
// Assigns |
// |
assign or1200_clk = wb_clk; |
assign or1200_rst = wb_rst | or1200_dbg_rst; |
|
// |
// Instantiation |
// |
or1200_top or1200_top0 |
( |
// Instruction bus, clocks, reset |
.iwb_clk_i (wb_clk), |
.iwb_rst_i (wb_rst), |
.iwb_ack_i (wbm_i_or12_ack_i), |
.iwb_err_i (wbm_i_or12_err_i), |
.iwb_rty_i (wbm_i_or12_rty_i), |
.iwb_dat_i (wbm_i_or12_dat_i), |
|
.iwb_cyc_o (wbm_i_or12_cyc_o), |
.iwb_adr_o (wbm_i_or12_adr_o), |
.iwb_stb_o (wbm_i_or12_stb_o), |
.iwb_we_o (wbm_i_or12_we_o), |
.iwb_sel_o (wbm_i_or12_sel_o), |
.iwb_dat_o (wbm_i_or12_dat_o), |
.iwb_cti_o (wbm_i_or12_cti_o), |
.iwb_bte_o (wbm_i_or12_bte_o), |
|
// Data bus, clocks, reset |
.dwb_clk_i (wb_clk), |
.dwb_rst_i (wb_rst), |
.dwb_ack_i (wbm_d_or12_ack_i), |
.dwb_err_i (wbm_d_or12_err_i), |
.dwb_rty_i (wbm_d_or12_rty_i), |
.dwb_dat_i (wbm_d_or12_dat_i), |
|
.dwb_cyc_o (wbm_d_or12_cyc_o), |
.dwb_adr_o (wbm_d_or12_adr_o), |
.dwb_stb_o (wbm_d_or12_stb_o), |
.dwb_we_o (wbm_d_or12_we_o), |
.dwb_sel_o (wbm_d_or12_sel_o), |
.dwb_dat_o (wbm_d_or12_dat_o), |
.dwb_cti_o (wbm_d_or12_cti_o), |
.dwb_bte_o (wbm_d_or12_bte_o), |
|
// Debug interface ports |
.dbg_stall_i (or1200_dbg_stall_i), |
//.dbg_ewt_i (or1200_dbg_ewt_i), |
.dbg_ewt_i (1'b0), |
.dbg_lss_o (or1200_dbg_lss_o), |
.dbg_is_o (or1200_dbg_is_o), |
.dbg_wp_o (or1200_dbg_wp_o), |
.dbg_bp_o (or1200_dbg_bp_o), |
|
.dbg_adr_i (or1200_dbg_adr_i), |
.dbg_we_i (or1200_dbg_we_i ), |
.dbg_stb_i (or1200_dbg_stb_i), |
.dbg_dat_i (or1200_dbg_dat_i), |
.dbg_dat_o (or1200_dbg_dat_o), |
.dbg_ack_o (or1200_dbg_ack_o), |
|
.pm_clksd_o (), |
.pm_dc_gate_o (), |
.pm_ic_gate_o (), |
.pm_dmmu_gate_o (), |
.pm_immu_gate_o (), |
.pm_tt_gate_o (), |
.pm_cpu_gate_o (), |
.pm_wakeup_o (), |
.pm_lvolt_o (), |
|
// Core clocks, resets |
.clk_i (or1200_clk), |
.rst_i (or1200_rst), |
|
.clmode_i (2'b00), |
// Interrupts |
.pic_ints_i (or1200_pic_ints), |
.sig_tick(sig_tick), |
/* |
.mbist_so_o (), |
.mbist_si_i (0), |
.mbist_ctrl_i (0), |
*/ |
|
.pm_cpustall_i (1'b0) |
|
); |
|
//////////////////////////////////////////////////////////////////////// |
|
|
`ifdef JTAG_DEBUG |
//////////////////////////////////////////////////////////////////////// |
// |
// OR1200 Debug Interface |
// |
//////////////////////////////////////////////////////////////////////// |
|
dbg_if dbg_if0 |
( |
// OR1200 interface |
.cpu0_clk_i (or1200_clk), |
.cpu0_rst_o (or1200_dbg_rst), |
.cpu0_addr_o (or1200_dbg_adr_i), |
.cpu0_data_o (or1200_dbg_dat_i), |
.cpu0_stb_o (or1200_dbg_stb_i), |
.cpu0_we_o (or1200_dbg_we_i), |
.cpu0_data_i (or1200_dbg_dat_o), |
.cpu0_ack_i (or1200_dbg_ack_o), |
|
|
.cpu0_stall_o (or1200_dbg_stall_i), |
.cpu0_bp_i (or1200_dbg_bp_o), |
|
// TAP interface |
.tck_i (dbg_tck), |
.tdi_i (jtag_tap_tdo), |
.tdo_o (dbg_if_tdo), |
.rst_i (wb_rst), |
.shift_dr_i (jtag_tap_shift_dr), |
.pause_dr_i (jtag_tap_pause_dr), |
.update_dr_i (jtag_tap_update_dr), |
.debug_select_i (dbg_if_select), |
|
// Wishbone debug master |
.wb_clk_i (wb_clk), |
.wb_dat_i (wbm_d_dbg_dat_i), |
.wb_ack_i (wbm_d_dbg_ack_i), |
.wb_err_i (wbm_d_dbg_err_i), |
.wb_adr_o (wbm_d_dbg_adr_o), |
.wb_dat_o (wbm_d_dbg_dat_o), |
.wb_cyc_o (wbm_d_dbg_cyc_o), |
.wb_stb_o (wbm_d_dbg_stb_o), |
.wb_sel_o (wbm_d_dbg_sel_o), |
.wb_we_o (wbm_d_dbg_we_o ), |
.wb_cti_o (wbm_d_dbg_cti_o), |
.wb_cab_o (/* UNUSED */), |
.wb_bte_o (wbm_d_dbg_bte_o) |
); |
|
//////////////////////////////////////////////////////////////////////// |
`else // !`ifdef JTAG_DEBUG |
|
assign wbm_d_dbg_adr_o = 0; |
assign wbm_d_dbg_dat_o = 0; |
assign wbm_d_dbg_cyc_o = 0; |
assign wbm_d_dbg_stb_o = 0; |
assign wbm_d_dbg_sel_o = 0; |
assign wbm_d_dbg_we_o = 0; |
assign wbm_d_dbg_cti_o = 0; |
assign wbm_d_dbg_bte_o = 0; |
|
assign or1200_dbg_adr_i = 0; |
assign or1200_dbg_dat_i = 0; |
assign or1200_dbg_stb_i = 0; |
assign or1200_dbg_we_i = 0; |
assign or1200_dbg_stall_i = 0; |
|
//////////////////////////////////////////////////////////////////////// |
`endif // !`ifdef JTAG_DEBUG |
|
`ifdef XILINX_DDR2 |
//////////////////////////////////////////////////////////////////////// |
// |
// Xilinx MIG DDR2 controller, Wishbone interface |
// |
//////////////////////////////////////////////////////////////////////// |
xilinx_s3adsp_ddr2 xilinx_s3adsp_ddr2 |
( |
.wbm0_adr_i (wbm_eth0_adr_o), |
.wbm0_bte_i (wbm_eth0_bte_o), |
.wbm0_cti_i (wbm_eth0_cti_o), |
.wbm0_cyc_i (wbm_eth0_cyc_o), |
.wbm0_dat_i (wbm_eth0_dat_o), |
.wbm0_sel_i (wbm_eth0_sel_o), |
.wbm0_stb_i (wbm_eth0_stb_o), |
.wbm0_we_i (wbm_eth0_we_o), |
.wbm0_ack_o (wbm_eth0_ack_i), |
.wbm0_err_o (wbm_eth0_err_i), |
.wbm0_rty_o (wbm_eth0_rty_i), |
.wbm0_dat_o (wbm_eth0_dat_i), |
|
.wbm1_adr_i (wbs_d_mc0_adr_i), |
.wbm1_bte_i (wbs_d_mc0_bte_i), |
.wbm1_cti_i (wbs_d_mc0_cti_i), |
.wbm1_cyc_i (wbs_d_mc0_cyc_i), |
.wbm1_dat_i (wbs_d_mc0_dat_i), |
.wbm1_sel_i (wbs_d_mc0_sel_i), |
.wbm1_stb_i (wbs_d_mc0_stb_i), |
.wbm1_we_i (wbs_d_mc0_we_i), |
.wbm1_ack_o (wbs_d_mc0_ack_o), |
.wbm1_err_o (wbs_d_mc0_err_o), |
.wbm1_rty_o (wbs_d_mc0_rty_o), |
.wbm1_dat_o (wbs_d_mc0_dat_o), |
|
.wbm2_adr_i (wbs_i_mc0_adr_i), |
.wbm2_bte_i (wbs_i_mc0_bte_i), |
.wbm2_cti_i (wbs_i_mc0_cti_i), |
.wbm2_cyc_i (wbs_i_mc0_cyc_i), |
.wbm2_dat_i (wbs_i_mc0_dat_i), |
.wbm2_sel_i (wbs_i_mc0_sel_i), |
.wbm2_stb_i (wbs_i_mc0_stb_i), |
.wbm2_we_i (wbs_i_mc0_we_i), |
.wbm2_ack_o (wbs_i_mc0_ack_o), |
.wbm2_err_o (wbs_i_mc0_err_o), |
.wbm2_rty_o (wbs_i_mc0_rty_o), |
.wbm2_dat_o (wbs_i_mc0_dat_o), |
|
.wb_clk (wb_clk), |
.wb_rst (wb_rst), |
|
.ddr2_dq (ddr2_dq), |
.ddr2_a (ddr2_a), |
.ddr2_ba (ddr2_ba), |
.ddr2_cke (ddr2_cke), |
.ddr2_cs_n (ddr2_cs_n), |
.ddr2_ras_n (ddr2_ras_n), |
.ddr2_cas_n (ddr2_cas_n), |
.ddr2_we_n (ddr2_we_n), |
.ddr2_odt (ddr2_odt), |
.ddr2_dm (ddr2_dm), |
.ddr2_dqs (ddr2_dqs), |
.ddr2_dqs_n (ddr2_dqs_n), |
.ddr2_ck (ddr2_ck), |
.ddr2_ck_n (ddr2_ck_n), |
.ddr2_rst_dqs_div_in (ddr2_rst_dqs_div_in), |
.ddr2_rst_dqs_div_out (ddr2_rst_dqs_div_out), |
|
.clk133_i (clk133) |
); |
|
`endif |
|
|
//////////////////////////////////////////////////////////////////////// |
// |
// ROM |
// |
//////////////////////////////////////////////////////////////////////// |
|
rom rom0 |
( |
.wb_dat_o (wbs_i_rom0_dat_o), |
.wb_ack_o (wbs_i_rom0_ack_o), |
.wb_adr_i (wbs_i_rom0_adr_i[(wbs_i_rom0_addr_width+2)-1:2]), |
.wb_stb_i (wbs_i_rom0_stb_i), |
.wb_cyc_i (wbs_i_rom0_cyc_i), |
.wb_cti_i (wbs_i_rom0_cti_i), |
.wb_bte_i (wbs_i_rom0_bte_i), |
.wb_clk (wb_clk), |
.wb_rst (wb_rst)); |
|
defparam rom0.addr_width = wbs_i_rom0_addr_width; |
|
assign wbs_i_rom0_err_o = 0; |
assign wbs_i_rom0_rty_o = 0; |
|
//////////////////////////////////////////////////////////////////////// |
|
`ifdef RAM_WB |
//////////////////////////////////////////////////////////////////////// |
// |
// Generic RAM |
// |
//////////////////////////////////////////////////////////////////////// |
|
ram_wb ram_wb0 |
( |
// Wishbone slave interface 0 |
.wbm0_dat_i (wbs_i_mc0_dat_i), |
.wbm0_adr_i (wbs_i_mc0_adr_i), |
.wbm0_sel_i (wbs_i_mc0_sel_i), |
.wbm0_cti_i (wbs_i_mc0_cti_i), |
.wbm0_bte_i (wbs_i_mc0_bte_i), |
.wbm0_we_i (wbs_i_mc0_we_i ), |
.wbm0_cyc_i (wbs_i_mc0_cyc_i), |
.wbm0_stb_i (wbs_i_mc0_stb_i), |
.wbm0_dat_o (wbs_i_mc0_dat_o), |
.wbm0_ack_o (wbs_i_mc0_ack_o), |
.wbm0_err_o (wbs_i_mc0_err_o), |
.wbm0_rty_o (wbs_i_mc0_rty_o), |
// Wishbone slave interface 1 |
.wbm1_dat_i (wbs_d_mc0_dat_i), |
.wbm1_adr_i (wbs_d_mc0_adr_i), |
.wbm1_sel_i (wbs_d_mc0_sel_i), |
.wbm1_cti_i (wbs_d_mc0_cti_i), |
.wbm1_bte_i (wbs_d_mc0_bte_i), |
.wbm1_we_i (wbs_d_mc0_we_i ), |
.wbm1_cyc_i (wbs_d_mc0_cyc_i), |
.wbm1_stb_i (wbs_d_mc0_stb_i), |
.wbm1_dat_o (wbs_d_mc0_dat_o), |
.wbm1_ack_o (wbs_d_mc0_ack_o), |
.wbm1_err_o (wbs_d_mc0_err_o), |
.wbm1_rty_o (wbs_d_mc0_rty_o), |
// Wishbone slave interface 2 |
.wbm2_dat_i (wbm_eth0_dat_o), |
.wbm2_adr_i (wbm_eth0_adr_o), |
.wbm2_sel_i (wbm_eth0_sel_o), |
.wbm2_cti_i (wbm_eth0_cti_o), |
.wbm2_bte_i (wbm_eth0_bte_o), |
.wbm2_we_i (wbm_eth0_we_o ), |
.wbm2_cyc_i (wbm_eth0_cyc_o), |
.wbm2_stb_i (wbm_eth0_stb_o), |
.wbm2_dat_o (wbm_eth0_dat_i), |
.wbm2_ack_o (wbm_eth0_ack_i), |
.wbm2_err_o (wbm_eth0_err_i), |
.wbm2_rty_o (wbm_eth0_rty_i), |
// Clock, reset |
.wb_clk_i (wb_clk), |
.wb_rst_i (wb_rst)); |
|
defparam ram_wb0.aw = wb_aw; |
defparam ram_wb0.dw = wb_dw; |
|
defparam ram_wb0.mem_size_bytes = (8192*1024); // 8MB |
defparam ram_wb0.mem_adr_width = 23; // log2(8192*1024) |
//////////////////////////////////////////////////////////////////////// |
`endif // `ifdef RAM_WB |
|
|
`ifdef ETH0 |
|
// |
// Wires |
// |
wire eth0_irq; |
wire [3:0] eth0_mtxd; |
wire eth0_mtxen; |
wire eth0_mtxerr; |
wire eth0_mtx_clk; |
wire eth0_mrx_clk; |
wire [3:0] eth0_mrxd; |
wire eth0_mrxdv; |
wire eth0_mrxerr; |
wire eth0_mcoll; |
wire eth0_mcrs; |
wire eth0_speed; |
wire eth0_duplex; |
wire eth0_link; |
// Management interface wires |
wire eth0_md_i; |
wire eth0_md_o; |
wire eth0_md_oe; |
|
|
// |
// assigns |
|
// Hook up MII wires |
assign eth0_mtx_clk = eth0_tx_clk; |
assign eth0_tx_data = eth0_mtxd[3:0]; |
assign eth0_tx_en = eth0_mtxen; |
assign eth0_tx_er = eth0_mtxerr; |
assign eth0_mrxd[3:0] = eth0_rx_data; |
assign eth0_mrxdv = eth0_dv; |
assign eth0_mrxerr = eth0_rx_er; |
assign eth0_mrx_clk = eth0_rx_clk; |
assign eth0_mcoll = eth0_col; |
assign eth0_mcrs = eth0_crs; |
|
`ifdef XILINX |
// Xilinx primitive for MDIO tristate |
IOBUF iobuf_phy_smi_data |
( |
// Outputs |
.O (eth0_md_i), |
// Inouts |
.IO (eth0_md_pad_io), |
// Inputs |
.I (eth0_md_o), |
.T (!eth0_md_oe)); |
`else // !`ifdef XILINX |
|
// Generic technology tristate control for management interface |
assign eth0_md_pad_io = eth0_md_oe ? eth0_md_o : 1'bz; |
assign eth0_md_i = eth0_md_pad_io; |
|
`endif // !`ifdef XILINX |
|
`ifdef ETH0_PHY_RST |
assign eth0_rst_n_o = !wb_rst; |
`endif |
|
ethmac ethmac0 |
( |
// Wishbone Slave interface |
.wb_clk_i (wb_clk), |
.wb_rst_i (wb_rst), |
.wb_dat_i (wbs_d_eth0_dat_i[31:0]), |
.wb_adr_i (wbs_d_eth0_adr_i[wbs_d_eth0_addr_width-1:2]), |
.wb_sel_i (wbs_d_eth0_sel_i[3:0]), |
.wb_we_i (wbs_d_eth0_we_i), |
.wb_cyc_i (wbs_d_eth0_cyc_i), |
.wb_stb_i (wbs_d_eth0_stb_i), |
.wb_dat_o (wbs_d_eth0_dat_o[31:0]), |
.wb_err_o (wbs_d_eth0_err_o), |
.wb_ack_o (wbs_d_eth0_ack_o), |
// Wishbone Master Interface |
.m_wb_adr_o (wbm_eth0_adr_o[31:0]), |
.m_wb_sel_o (wbm_eth0_sel_o[3:0]), |
.m_wb_we_o (wbm_eth0_we_o), |
.m_wb_dat_o (wbm_eth0_dat_o[31:0]), |
.m_wb_cyc_o (wbm_eth0_cyc_o), |
.m_wb_stb_o (wbm_eth0_stb_o), |
.m_wb_cti_o (wbm_eth0_cti_o[2:0]), |
.m_wb_bte_o (wbm_eth0_bte_o[1:0]), |
.m_wb_dat_i (wbm_eth0_dat_i[31:0]), |
.m_wb_ack_i (wbm_eth0_ack_i), |
.m_wb_err_i (wbm_eth0_err_i), |
|
// Ethernet MII interface |
// Transmit |
.mtxd_pad_o (eth0_mtxd[3:0]), |
.mtxen_pad_o (eth0_mtxen), |
.mtxerr_pad_o (eth0_mtxerr), |
.mtx_clk_pad_i (eth0_mtx_clk), |
// Receive |
.mrx_clk_pad_i (eth0_mrx_clk), |
.mrxd_pad_i (eth0_mrxd[3:0]), |
.mrxdv_pad_i (eth0_mrxdv), |
.mrxerr_pad_i (eth0_mrxerr), |
.mcoll_pad_i (eth0_mcoll), |
.mcrs_pad_i (eth0_mcrs), |
// Management interface |
.md_pad_i (eth0_md_i), |
.mdc_pad_o (eth0_mdc_pad_o), |
.md_pad_o (eth0_md_o), |
.md_padoe_o (eth0_md_oe), |
|
// Processor interrupt |
.int_o (eth0_irq) |
|
/* |
.mbist_so_o (), |
.mbist_si_i (), |
.mbist_ctrl_i () |
*/ |
|
); |
|
assign wbs_d_eth0_rty_o = 0; |
|
`else |
assign wbs_d_eth0_dat_o = 0; |
assign wbs_d_eth0_err_o = 0; |
assign wbs_d_eth0_ack_o = 0; |
assign wbs_d_eth0_rty_o = 0; |
assign wbm_eth0_adr_o = 0; |
assign wbm_eth0_sel_o = 0; |
assign wbm_eth0_we_o = 0; |
assign wbm_eth0_dat_o = 0; |
assign wbm_eth0_cyc_o = 0; |
assign wbm_eth0_stb_o = 0; |
assign wbm_eth0_cti_o = 0; |
assign wbm_eth0_bte_o = 0; |
`endif |
|
`ifdef UART0 |
//////////////////////////////////////////////////////////////////////// |
// |
// UART0 |
// |
//////////////////////////////////////////////////////////////////////// |
|
// |
// Wires |
// |
wire uart0_srx; |
wire uart0_stx; |
|
wire uart0_irq; |
|
// |
// Assigns |
// |
assign wbs_d_uart0_err_o = 0; |
assign wbs_d_uart0_rty_o = 0; |
|
// Two UART lines coming to single one (ensure they go high when unconnected) |
assign uart0_srx = uart0_srx_pad_i & uart0_srx_expheader_pad_i; |
assign uart0_stx_pad_o = uart0_stx; |
assign uart0_stx_expheader_pad_o = uart0_stx; |
|
|
uart16550 uart16550_0 |
( |
// Wishbone slave interface |
.wb_clk_i (wb_clk), |
.wb_rst_i (wb_rst), |
.wb_adr_i (wbs_d_uart0_adr_i[uart0_addr_width-1:0]), |
.wb_dat_i (wbs_d_uart0_dat_i), |
.wb_we_i (wbs_d_uart0_we_i), |
.wb_stb_i (wbs_d_uart0_stb_i), |
.wb_cyc_i (wbs_d_uart0_cyc_i), |
//.wb_sel_i (), |
.wb_dat_o (wbs_d_uart0_dat_o), |
.wb_ack_o (wbs_d_uart0_ack_o), |
|
.int_o (uart0_irq), |
.stx_pad_o (uart0_stx), |
.rts_pad_o (), |
.dtr_pad_o (), |
// .baud_o (), |
// Inputs |
.srx_pad_i (uart0_srx), |
.cts_pad_i (1'b0), |
.dsr_pad_i (1'b0), |
.ri_pad_i (1'b0), |
.dcd_pad_i (1'b0)); |
|
//////////////////////////////////////////////////////////////////////// |
`else // !`ifdef UART0 |
|
// |
// Assigns |
// |
assign wbs_d_uart0_err_o = 0; |
assign wbs_d_uart0_rty_o = 0; |
assign wbs_d_uart0_ack_o = 0; |
assign wbs_d_uart0_dat_o = 0; |
|
//////////////////////////////////////////////////////////////////////// |
`endif // !`ifdef UART0 |
|
`ifdef SPI0 |
//////////////////////////////////////////////////////////////////////// |
// |
// SPI0 controller |
// |
//////////////////////////////////////////////////////////////////////// |
|
// |
// Wires |
// |
wire spi0_irq; |
|
// |
// Assigns |
// |
assign wbs_d_spi0_err_o = 0; |
assign wbs_d_spi0_rty_o = 0; |
//assign spi0_hold_n_o = 1; |
//assign spi0_w_n_o = 1; |
|
|
simple_spi spi0 |
( |
// Wishbone slave interface |
.clk_i (wb_clk), |
.rst_i (wb_rst), |
.cyc_i (wbs_d_spi0_cyc_i), |
.stb_i (wbs_d_spi0_stb_i), |
.adr_i (wbs_d_spi0_adr_i[spi0_wb_adr_width-1:0]), |
.we_i (wbs_d_spi0_we_i), |
.dat_i (wbs_d_spi0_dat_i), |
.dat_o (wbs_d_spi0_dat_o), |
.ack_o (wbs_d_spi0_ack_o), |
// SPI IRQ |
.inta_o (spi0_irq), |
// External SPI interface |
.sck_o (spi0_sck_o), |
.ss_o (spi0_ss_o), |
.mosi_o (spi0_mosi_o), |
.miso_i (spi0_miso_i) |
); |
|
defparam spi0.slave_select_width = spi0_ss_width; |
|
//////////////////////////////////////////////////////////////////////// |
`else // !`ifdef SPI0 |
|
// |
// Assigns |
// |
assign wbs_d_spi0_dat_o = 0; |
assign wbs_d_spi0_ack_o = 0; |
assign wbs_d_spi0_err_o = 0; |
assign wbs_d_spi0_rty_o = 0; |
|
//////////////////////////////////////////////////////////////////////// |
`endif // !`ifdef SPI0 |
|
|
`ifdef I2C0 |
//////////////////////////////////////////////////////////////////////// |
// |
// i2c controller 0 |
// |
//////////////////////////////////////////////////////////////////////// |
|
// |
// Wires |
// |
wire i2c0_irq; |
wire scl0_pad_o; |
wire scl0_padoen_o; |
wire sda0_pad_o; |
wire sda0_padoen_o; |
|
i2c_master_slave |
# |
( |
.DEFAULT_SLAVE_ADDR(HV0_SADR) |
) |
i2c_master_slave0 |
( |
.wb_clk_i (wb_clk), |
.wb_rst_i (wb_rst), |
.arst_i (wb_rst), |
.wb_adr_i (wbs_d_i2c0_adr_i[i2c_0_wb_adr_width-1:0]), |
.wb_dat_i (wbs_d_i2c0_dat_i), |
.wb_we_i (wbs_d_i2c0_we_i ), |
.wb_cyc_i (wbs_d_i2c0_cyc_i), |
.wb_stb_i (wbs_d_i2c0_stb_i), |
.wb_dat_o (wbs_d_i2c0_dat_o), |
.wb_ack_o (wbs_d_i2c0_ack_o), |
.scl_pad_i (i2c0_scl_io ), |
.scl_pad_o (scl0_pad_o ), |
.scl_padoen_o (scl0_padoen_o ), |
.sda_pad_i (i2c0_sda_io ), |
.sda_pad_o (sda0_pad_o ), |
.sda_padoen_o (sda0_padoen_o ), |
|
// Interrupt |
.wb_inta_o (i2c0_irq) |
|
); |
|
assign wbs_d_i2c0_err_o = 0; |
assign wbs_d_i2c0_rty_o = 0; |
|
// i2c phy lines |
assign i2c0_scl_io = scl0_padoen_o ? 1'bz : scl0_pad_o; |
assign i2c0_sda_io = sda0_padoen_o ? 1'bz : sda0_pad_o; |
|
|
//////////////////////////////////////////////////////////////////////// |
`else // !`ifdef I2C0 |
|
assign wbs_d_i2c0_dat_o = 0; |
assign wbs_d_i2c0_ack_o = 0; |
assign wbs_d_i2c0_err_o = 0; |
assign wbs_d_i2c0_rty_o = 0; |
|
//////////////////////////////////////////////////////////////////////// |
`endif // !`ifdef I2C0 |
|
`ifdef GPIO0 |
//////////////////////////////////////////////////////////////////////// |
// |
// GPIO 0 |
// |
//////////////////////////////////////////////////////////////////////// |
|
gpio gpio0 |
( |
// GPIO bus |
.gpio_io (gpio0_io[gpio0_io_width-1:0]), |
// Wishbone slave interface |
.wb_adr_i (wbs_d_gpio0_adr_i[gpio0_wb_adr_width-1:0]), |
.wb_dat_i (wbs_d_gpio0_dat_i), |
.wb_we_i (wbs_d_gpio0_we_i), |
.wb_cyc_i (wbs_d_gpio0_cyc_i), |
.wb_stb_i (wbs_d_gpio0_stb_i), |
.wb_cti_i (wbs_d_gpio0_cti_i), |
.wb_bte_i (wbs_d_gpio0_bte_i), |
.wb_dat_o (wbs_d_gpio0_dat_o), |
.wb_ack_o (wbs_d_gpio0_ack_o), |
.wb_err_o (wbs_d_gpio0_err_o), |
.wb_rty_o (wbs_d_gpio0_rty_o), |
|
.wb_clk (wb_clk), |
.wb_rst (wb_rst) |
); |
|
defparam gpio0.gpio_io_width = gpio0_io_width; |
defparam gpio0.gpio_dir_reset_val = gpio0_dir_reset_val; |
defparam gpio0.gpio_o_reset_val = gpio0_o_reset_val; |
|
//////////////////////////////////////////////////////////////////////// |
`else // !`ifdef GPIO0 |
assign wbs_d_gpio0_dat_o = 0; |
assign wbs_d_gpio0_ack_o = 0; |
assign wbs_d_gpio0_err_o = 0; |
assign wbs_d_gpio0_rty_o = 0; |
//////////////////////////////////////////////////////////////////////// |
`endif // !`ifdef GPIO0 |
|
//////////////////////////////////////////////////////////////////////// |
// |
// OR1200 Interrupt assignment |
// |
//////////////////////////////////////////////////////////////////////// |
|
assign or1200_pic_ints[0] = 0; // Non-maskable inside OR1200 |
assign or1200_pic_ints[1] = 0; // Non-maskable inside OR1200 |
`ifdef UART0 |
assign or1200_pic_ints[2] = uart0_irq; |
`else |
assign or1200_pic_ints[2] = 0; |
`endif |
assign or1200_pic_ints[3] = 0; |
`ifdef ETH0 |
assign or1200_pic_ints[4] = eth0_irq; |
`else |
assign or1200_pic_ints[4] = 0; |
`endif |
assign or1200_pic_ints[5] = 0; |
`ifdef SPI0 |
assign or1200_pic_ints[6] = spi0_irq; |
`else |
assign or1200_pic_ints[6] = 0; |
`endif |
assign or1200_pic_ints[7] = 0; |
assign or1200_pic_ints[8] = 0; |
assign or1200_pic_ints[9] = 0; |
`ifdef I2C0 |
assign or1200_pic_ints[10] = i2c0_irq; |
`else |
assign or1200_pic_ints[10] = 0; |
`endif |
assign or1200_pic_ints[11] = 0; |
assign or1200_pic_ints[12] = 0; |
assign or1200_pic_ints[13] = 0; |
assign or1200_pic_ints[14] = 0; |
assign or1200_pic_ints[15] = 0; |
assign or1200_pic_ints[16] = 0; |
assign or1200_pic_ints[17] = 0; |
assign or1200_pic_ints[18] = 0; |
assign or1200_pic_ints[19] = 0; |
assign or1200_pic_ints[20] = 0; |
assign or1200_pic_ints[21] = 0; |
assign or1200_pic_ints[22] = 0; |
assign or1200_pic_ints[23] = 0; |
assign or1200_pic_ints[24] = 0; |
assign or1200_pic_ints[25] = 0; |
assign or1200_pic_ints[26] = 0; |
assign or1200_pic_ints[27] = 0; |
assign or1200_pic_ints[28] = 0; |
assign or1200_pic_ints[29] = 0; |
assign or1200_pic_ints[30] = 0; |
|
endmodule // orpsoc_top |
|
|
/s3adsp1800/rtl/verilog/arbiter/arbiter_bytebus.v
0,0 → 1,1192
////////////////////////////////////////////////////////////////////// |
/// //// |
/// Wishbone arbiter, byte-wide data path, no bursting //// |
/// //// |
/// Simple arbiter, single master, multiple slave, for byte-wide //// |
/// peripherals //// |
/// //// |
/// Julius Baxter, julius@opencores.org //// |
/// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009, 2010 Authors and 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
// |
// Things to update when changing slave config: |
// |
// 1. Port list |
// 2. Port specification |
// 3. Slave addr select parameter |
// 4. Slave addr selects |
// 5. Slave input mux logic |
// 6. The four different master out mux logics (dat_o mux, and ack, rty & err) |
// |
`include "orpsoc-defines.v" |
module arbiter_bytebus |
( |
|
// Master in |
wbm0_adr_o, |
wbm0_dat_o, |
wbm0_sel_o, |
wbm0_we_o, |
wbm0_cyc_o, |
wbm0_stb_o, |
wbm0_cti_o, |
wbm0_bte_o, |
wbm0_dat_i, |
wbm0_ack_i, |
wbm0_err_i, |
wbm0_rty_i, |
|
// Slave one |
// Wishbone Slave interface |
wbs0_adr_i, |
wbs0_dat_i, |
wbs0_we_i, |
wbs0_cyc_i, |
wbs0_stb_i, |
wbs0_cti_i, |
wbs0_bte_i, |
wbs0_dat_o, |
wbs0_ack_o, |
wbs0_err_o, |
wbs0_rty_o, |
|
// Slave two |
// Wishbone Slave interface |
wbs1_adr_i, |
wbs1_dat_i, |
wbs1_we_i, |
wbs1_cyc_i, |
wbs1_stb_i, |
wbs1_cti_i, |
wbs1_bte_i, |
wbs1_dat_o, |
wbs1_ack_o, |
wbs1_err_o, |
wbs1_rty_o, |
|
// Slave three |
// Wishbone Slave interface |
wbs2_adr_i, |
wbs2_dat_i, |
wbs2_we_i, |
wbs2_cyc_i, |
wbs2_stb_i, |
wbs2_cti_i, |
wbs2_bte_i, |
wbs2_dat_o, |
wbs2_ack_o, |
wbs2_err_o, |
wbs2_rty_o, |
|
// Slave four |
// Wishbone Slave interface |
wbs3_adr_i, |
wbs3_dat_i, |
wbs3_we_i, |
wbs3_cyc_i, |
wbs3_stb_i, |
wbs3_cti_i, |
wbs3_bte_i, |
wbs3_dat_o, |
wbs3_ack_o, |
wbs3_err_o, |
wbs3_rty_o, |
|
// Slave five |
// Wishbone Slave interface |
wbs4_adr_i, |
wbs4_dat_i, |
wbs4_we_i, |
wbs4_cyc_i, |
wbs4_stb_i, |
wbs4_cti_i, |
wbs4_bte_i, |
wbs4_dat_o, |
wbs4_ack_o, |
wbs4_err_o, |
wbs4_rty_o, |
/* |
// Slave six |
// Wishbone Slave interface |
wbs5_adr_i, |
wbs5_dat_i, |
wbs5_we_i, |
wbs5_cyc_i, |
wbs5_stb_i, |
wbs5_cti_i, |
wbs5_bte_i, |
wbs5_dat_o, |
wbs5_ack_o, |
wbs5_err_o, |
wbs5_rty_o, |
|
// Slave seven |
// Wishbone Slave interface |
wbs6_adr_i, |
wbs6_dat_i, |
wbs6_we_i, |
wbs6_cyc_i, |
wbs6_stb_i, |
wbs6_cti_i, |
wbs6_bte_i, |
wbs6_dat_o, |
wbs6_ack_o, |
wbs6_err_o, |
wbs6_rty_o, |
|
// Slave eight |
// Wishbone Slave interface |
wbs7_adr_i, |
wbs7_dat_i, |
wbs7_we_i, |
wbs7_cyc_i, |
wbs7_stb_i, |
wbs7_cti_i, |
wbs7_bte_i, |
wbs7_dat_o, |
wbs7_ack_o, |
wbs7_err_o, |
wbs7_rty_o, |
|
// Slave nine |
// Wishbone Slave interface |
wbs8_adr_i, |
wbs8_dat_i, |
wbs8_we_i, |
wbs8_cyc_i, |
wbs8_stb_i, |
wbs8_cti_i, |
wbs8_bte_i, |
wbs8_dat_o, |
wbs8_ack_o, |
wbs8_err_o, |
wbs8_rty_o, |
|
// Slave ten |
// Wishbone Slave interface |
wbs9_adr_i, |
wbs9_dat_i, |
wbs9_we_i, |
wbs9_cyc_i, |
wbs9_stb_i, |
wbs9_cti_i, |
wbs9_bte_i, |
wbs9_dat_o, |
wbs9_ack_o, |
wbs9_err_o, |
wbs9_rty_o, |
|
// Slave eleven |
// Wishbone Slave interface |
wbs10_adr_i, |
wbs10_dat_i, |
wbs10_we_i, |
wbs10_cyc_i, |
wbs10_stb_i, |
wbs10_cti_i, |
wbs10_bte_i, |
wbs10_dat_o, |
wbs10_ack_o, |
wbs10_err_o, |
wbs10_rty_o, |
|
// Slave twelve |
// Wishbone Slave interface |
wbs11_adr_i, |
wbs11_dat_i, |
wbs11_we_i, |
wbs11_cyc_i, |
wbs11_stb_i, |
wbs11_cti_i, |
wbs11_bte_i, |
wbs11_dat_o, |
wbs11_ack_o, |
wbs11_err_o, |
wbs11_rty_o, |
|
// Slave thirteen |
// Wishbone Slave interface |
wbs12_adr_i, |
wbs12_dat_i, |
wbs12_we_i, |
wbs12_cyc_i, |
wbs12_stb_i, |
wbs12_cti_i, |
wbs12_bte_i, |
wbs12_dat_o, |
wbs12_ack_o, |
wbs12_err_o, |
wbs12_rty_o, |
|
// Slave fourteen |
// Wishbone Slave interface |
wbs13_adr_i, |
wbs13_dat_i, |
wbs13_we_i, |
wbs13_cyc_i, |
wbs13_stb_i, |
wbs13_cti_i, |
wbs13_bte_i, |
wbs13_dat_o, |
wbs13_ack_o, |
wbs13_err_o, |
wbs13_rty_o, |
|
// Slave fifteen |
// Wishbone Slave interface |
wbs14_adr_i, |
wbs14_dat_i, |
wbs14_we_i, |
wbs14_cyc_i, |
wbs14_stb_i, |
wbs14_cti_i, |
wbs14_bte_i, |
wbs14_dat_o, |
wbs14_ack_o, |
wbs14_err_o, |
wbs14_rty_o, |
|
// Slave sixteen |
// Wishbone Slave interface |
wbs15_adr_i, |
wbs15_dat_i, |
wbs15_we_i, |
wbs15_cyc_i, |
wbs15_stb_i, |
wbs15_cti_i, |
wbs15_bte_i, |
|
wbs15_dat_o, |
wbs15_ack_o, |
wbs15_err_o, |
wbs15_rty_o, |
|
// Slave seventeen |
// Wishbone Slave interface |
wbs16_adr_i, |
wbs16_dat_i, |
wbs16_we_i, |
wbs16_cyc_i, |
wbs16_stb_i, |
wbs16_cti_i, |
wbs16_bte_i, |
|
wbs16_dat_o, |
wbs16_ack_o, |
wbs16_err_o, |
wbs16_rty_o, |
|
|
// Slave eighteen |
// Wishbone Slave interface |
wbs17_adr_i, |
wbs17_dat_i, |
wbs17_we_i, |
wbs17_cyc_i, |
wbs17_stb_i, |
wbs17_cti_i, |
wbs17_bte_i, |
|
wbs17_dat_o, |
wbs17_ack_o, |
wbs17_err_o, |
wbs17_rty_o, |
|
// Slave nineteen |
// Wishbone Slave interface |
wbs18_adr_i, |
wbs18_dat_i, |
wbs18_we_i, |
wbs18_cyc_i, |
wbs18_stb_i, |
wbs18_cti_i, |
wbs18_bte_i, |
|
wbs18_dat_o, |
wbs18_ack_o, |
wbs18_err_o, |
wbs18_rty_o, |
|
// Slave twenty |
// Wishbone Slave interface |
wbs19_adr_i, |
wbs19_dat_i, |
wbs19_we_i, |
wbs19_cyc_i, |
wbs19_stb_i, |
wbs19_cti_i, |
wbs19_bte_i, |
|
wbs19_dat_o, |
wbs19_ack_o, |
wbs19_err_o, |
wbs19_rty_o, |
|
*/ |
|
wb_clk, wb_rst |
); |
|
|
parameter wb_dat_width = 32; |
parameter wbs_dat_width = 8; |
parameter wb_adr_width = 32; |
|
parameter wb_addr_match_width = 8; |
|
parameter wb_num_slaves = 20; // Currently can handle up to 20 |
|
// Slave addresses |
|
parameter slave0_adr = 8'h00; |
parameter slave1_adr = 8'h00; |
parameter slave2_adr = 8'h00; |
parameter slave3_adr = 8'h00; |
parameter slave4_adr = 8'h00; |
parameter slave5_adr = 8'h00; |
parameter slave6_adr = 8'h00; |
parameter slave7_adr = 8'h00; |
parameter slave8_adr = 8'h00; |
parameter slave9_adr = 8'h00; |
parameter slave10_adr = 8'h00; |
parameter slave11_adr = 8'h00; |
parameter slave12_adr = 8'h00; |
parameter slave13_adr = 8'h00; |
parameter slave14_adr = 8'h00; |
parameter slave15_adr = 8'h00; |
parameter slave16_adr = 8'h00; |
parameter slave17_adr = 8'h00; |
parameter slave18_adr = 8'h00; |
parameter slave19_adr = 8'h00; |
|
|
`define WB_ARB_ADDR_MATCH_SEL wb_adr_width-1:wb_adr_width-wb_addr_match_width |
|
input wb_clk; |
input wb_rst; |
|
// WB Master one |
input [wb_adr_width-1:0] wbm0_adr_o; |
input [wb_dat_width-1:0] wbm0_dat_o; |
input [3:0] wbm0_sel_o; |
input wbm0_we_o; |
input wbm0_cyc_o; |
input wbm0_stb_o; |
input [2:0] wbm0_cti_o; |
input [1:0] wbm0_bte_o; |
output [wb_dat_width-1:0] wbm0_dat_i; |
output wbm0_ack_i; |
output wbm0_err_i; |
output wbm0_rty_i; |
|
|
// Slave one |
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs0_adr_i; |
output [wbs_dat_width-1:0] wbs0_dat_i; |
output wbs0_we_i; |
output wbs0_cyc_i; |
output wbs0_stb_i; |
output [2:0] wbs0_cti_i; |
output [1:0] wbs0_bte_i; |
input [wbs_dat_width-1:0] wbs0_dat_o; |
input wbs0_ack_o; |
input wbs0_err_o; |
input wbs0_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs1_adr_i; |
output [wbs_dat_width-1:0] wbs1_dat_i; |
output wbs1_we_i; |
output wbs1_cyc_i; |
output wbs1_stb_i; |
output [2:0] wbs1_cti_i; |
output [1:0] wbs1_bte_i; |
input [wbs_dat_width-1:0] wbs1_dat_o; |
input wbs1_ack_o; |
input wbs1_err_o; |
input wbs1_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs2_adr_i; |
output [wbs_dat_width-1:0] wbs2_dat_i; |
output wbs2_we_i; |
output wbs2_cyc_i; |
output wbs2_stb_i; |
output [2:0] wbs2_cti_i; |
output [1:0] wbs2_bte_i; |
input [wbs_dat_width-1:0] wbs2_dat_o; |
input wbs2_ack_o; |
input wbs2_err_o; |
input wbs2_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs3_adr_i; |
output [wbs_dat_width-1:0] wbs3_dat_i; |
output wbs3_we_i; |
output wbs3_cyc_i; |
output wbs3_stb_i; |
output [2:0] wbs3_cti_i; |
output [1:0] wbs3_bte_i; |
input [wbs_dat_width-1:0] wbs3_dat_o; |
input wbs3_ack_o; |
input wbs3_err_o; |
input wbs3_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs4_adr_i; |
output [wbs_dat_width-1:0] wbs4_dat_i; |
output wbs4_we_i; |
output wbs4_cyc_i; |
output wbs4_stb_i; |
output [2:0] wbs4_cti_i; |
output [1:0] wbs4_bte_i; |
input [wbs_dat_width-1:0] wbs4_dat_o; |
input wbs4_ack_o; |
input wbs4_err_o; |
input wbs4_rty_o; |
|
/* |
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs5_adr_i; |
output [wbs_dat_width-1:0] wbs5_dat_i; |
output wbs5_we_i; |
output wbs5_cyc_i; |
output wbs5_stb_i; |
output [2:0] wbs5_cti_i; |
output [1:0] wbs5_bte_i; |
input [wbs_dat_width-1:0] wbs5_dat_o; |
input wbs5_ack_o; |
input wbs5_err_o; |
input wbs5_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs6_adr_i; |
output [wbs_dat_width-1:0] wbs6_dat_i; |
output wbs6_we_i; |
output wbs6_cyc_i; |
output wbs6_stb_i; |
output [2:0] wbs6_cti_i; |
output [1:0] wbs6_bte_i; |
input [wbs_dat_width-1:0] wbs6_dat_o; |
input wbs6_ack_o; |
input wbs6_err_o; |
input wbs6_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs7_adr_i; |
output [wbs_dat_width-1:0] wbs7_dat_i; |
output wbs7_we_i; |
output wbs7_cyc_i; |
output wbs7_stb_i; |
output [2:0] wbs7_cti_i; |
output [1:0] wbs7_bte_i; |
input [wbs_dat_width-1:0] wbs7_dat_o; |
input wbs7_ack_o; |
input wbs7_err_o; |
input wbs7_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs8_adr_i; |
output [wbs_dat_width-1:0] wbs8_dat_i; |
output wbs8_we_i; |
output wbs8_cyc_i; |
output wbs8_stb_i; |
output [2:0] wbs8_cti_i; |
output [1:0] wbs8_bte_i; |
input [wbs_dat_width-1:0] wbs8_dat_o; |
input wbs8_ack_o; |
input wbs8_err_o; |
input wbs8_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs9_adr_i; |
output [wbs_dat_width-1:0] wbs9_dat_i; |
output wbs9_we_i; |
output wbs9_cyc_i; |
output wbs9_stb_i; |
output [2:0] wbs9_cti_i; |
output [1:0] wbs9_bte_i; |
input [wbs_dat_width-1:0] wbs9_dat_o; |
input wbs9_ack_o; |
input wbs9_err_o; |
input wbs9_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs10_adr_i; |
output [wbs_dat_width-1:0] wbs10_dat_i; |
output wbs10_we_i; |
output wbs10_cyc_i; |
output wbs10_stb_i; |
output [2:0] wbs10_cti_i; |
output [1:0] wbs10_bte_i; |
input [wbs_dat_width-1:0] wbs10_dat_o; |
input wbs10_ack_o; |
input wbs10_err_o; |
input wbs10_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs11_adr_i; |
output [wbs_dat_width-1:0] wbs11_dat_i; |
output wbs11_we_i; |
output wbs11_cyc_i; |
output wbs11_stb_i; |
output [2:0] wbs11_cti_i; |
output [1:0] wbs11_bte_i; |
input [wbs_dat_width-1:0] wbs11_dat_o; |
input wbs11_ack_o; |
input wbs11_err_o; |
input wbs11_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs12_adr_i; |
output [wbs_dat_width-1:0] wbs12_dat_i; |
output wbs12_we_i; |
output wbs12_cyc_i; |
output wbs12_stb_i; |
output [2:0] wbs12_cti_i; |
output [1:0] wbs12_bte_i; |
input [wbs_dat_width-1:0] wbs12_dat_o; |
input wbs12_ack_o; |
input wbs12_err_o; |
input wbs12_rty_o; |
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs13_adr_i; |
output [wbs_dat_width-1:0] wbs13_dat_i; |
output wbs13_we_i; |
output wbs13_cyc_i; |
output wbs13_stb_i; |
output [2:0] wbs13_cti_i; |
output [1:0] wbs13_bte_i; |
input [wbs_dat_width-1:0] wbs13_dat_o; |
input wbs13_ack_o; |
input wbs13_err_o; |
input wbs13_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs14_adr_i; |
output [wbs_dat_width-1:0] wbs14_dat_i; |
output wbs14_we_i; |
output wbs14_cyc_i; |
output wbs14_stb_i; |
output [2:0] wbs14_cti_i; |
output [1:0] wbs14_bte_i; |
input [wbs_dat_width-1:0] wbs14_dat_o; |
input wbs14_ack_o; |
input wbs14_err_o; |
input wbs14_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs15_adr_i; |
output [wbs_dat_width-1:0] wbs15_dat_i; |
output wbs15_we_i; |
output wbs15_cyc_i; |
output wbs15_stb_i; |
output [2:0] wbs15_cti_i; |
output [1:0] wbs15_bte_i; |
input [wbs_dat_width-1:0] wbs15_dat_o; |
input wbs15_ack_o; |
input wbs15_err_o; |
input wbs15_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs16_adr_i; |
output [wbs_dat_width-1:0] wbs16_dat_i; |
output wbs16_we_i; |
output wbs16_cyc_i; |
output wbs16_stb_i; |
output [2:0] wbs16_cti_i; |
output [1:0] wbs16_bte_i; |
input [wbs_dat_width-1:0] wbs16_dat_o; |
input wbs16_ack_o; |
input wbs16_err_o; |
input wbs16_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs17_adr_i; |
output [wbs_dat_width-1:0] wbs17_dat_i; |
output wbs17_we_i; |
output wbs17_cyc_i; |
output wbs17_stb_i; |
output [2:0] wbs17_cti_i; |
output [1:0] wbs17_bte_i; |
input [wbs_dat_width-1:0] wbs17_dat_o; |
input wbs17_ack_o; |
input wbs17_err_o; |
input wbs17_rty_o; |
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs18_adr_i; |
output [wbs_dat_width-1:0] wbs18_dat_i; |
output wbs18_we_i; |
output wbs18_cyc_i; |
output wbs18_stb_i; |
output [2:0] wbs18_cti_i; |
output [1:0] wbs18_bte_i; |
input [wbs_dat_width-1:0] wbs18_dat_o; |
input wbs18_ack_o; |
input wbs18_err_o; |
input wbs18_rty_o; |
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs19_adr_i; |
output [wbs_dat_width-1:0] wbs19_dat_i; |
output wbs19_we_i; |
output wbs19_cyc_i; |
output wbs19_stb_i; |
output [2:0] wbs19_cti_i; |
output [1:0] wbs19_bte_i; |
input [wbs_dat_width-1:0] wbs19_dat_o; |
input wbs19_ack_o; |
input wbs19_err_o; |
input wbs19_rty_o; |
*/ |
|
reg watchdog_err; |
|
// Master input mux output wires |
wire [wb_adr_width-1:0] wbm_adr_o; |
wire [wbs_dat_width-1:0] wbm_dat_o; |
wire [3:0] wbm_sel_o; |
wire wbm_we_o; |
wire wbm_cyc_o; |
wire wbm_stb_o; |
wire [2:0] wbm_cti_o; |
wire [1:0] wbm_bte_o; |
|
wire [wbs_dat_width-1:0] wbm_dat_byte_i; |
wire wbm_ack_i; |
wire wbm_err_i; |
wire wbm_rty_i; |
|
|
// Master input mux (not really used, only one master on this bus) |
assign wbm_adr_o = wbm0_adr_o; |
|
// Select the right byte and put it on the data out line |
// !BIG ENDIAN! |
assign wbm_dat_o = wbm0_sel_o[3] ? wbm0_dat_o[31:24] : |
wbm0_sel_o[2] ? wbm0_dat_o[23:16] : |
wbm0_sel_o[1] ? wbm0_dat_o[15:8] : |
wbm0_dat_o[7:0]; |
|
assign wbm_we_o = wbm0_we_o; |
|
assign wbm_cyc_o = wbm0_stb_o; |
|
assign wbm_stb_o = wbm0_stb_o; |
|
// Will we really need these for byte-peripherals |
assign wbm_cti_o = wbm0_cti_o; |
|
assign wbm_bte_o = wbm0_bte_o; |
|
// Signals back to the master |
assign wbm0_dat_i = (wbm0_sel_o[3]) ? {wbm_dat_byte_i, 24'd0} : |
(wbm0_sel_o[2]) ? {8'd0, wbm_dat_byte_i, 16'd0} : |
(wbm0_sel_o[1]) ? {16'd0, wbm_dat_byte_i, 8'd0} : |
{24'd0, wbm_dat_byte_i}; |
|
assign wbm0_ack_i = wbm_ack_i; |
assign wbm0_err_i = wbm_err_i; |
assign wbm0_rty_i = wbm_rty_i; |
|
`ifdef ARBITER_BYTEBUS_WATCHDOG |
reg [`ARBITER_BYTEBUS_WATCHDOG_TIMER_WIDTH:0] watchdog_timer; |
reg wbm_stb_r; // Register strobe |
wire wbm_stb_edge; // Detect its edge |
|
always @(posedge wb_clk) |
wbm_stb_r <= wbm_stb_o; |
|
assign wbm_stb_edge = (wbm_stb_o & !wbm_stb_r); |
|
// Counter logic |
always @(posedge wb_clk) |
if (wb_rst) watchdog_timer <= 0; |
else if (wbm_ack_i) // When we see an ack, turn off timer |
watchdog_timer <= 0; |
else if (wbm_stb_edge) // New access means start timer again |
watchdog_timer <= 1; |
else if (|watchdog_timer) // Continue counting if counter > 0 |
watchdog_timer <= watchdog_timer + 1; |
|
always @(posedge wb_clk) |
watchdog_err <= (&watchdog_timer); |
|
`else // !`ifdef ARBITER_BYTEBUS_WATCHDOG |
always @(posedge wb_clk) |
watchdog_err <= 0; |
|
`endif // !`ifdef ARBITER_BYTEBUS_WATCHDOG |
|
|
// Wishbone slave mux out wires |
wire [wb_adr_width-1:0] wbs_adr_i; |
wire [wbs_dat_width-1:0] wbs_dat_i; |
wire wbs_we_i; |
wire wbs_cyc_i; |
wire wbs_stb_i; |
wire [2:0] wbs_cti_i; |
wire [1:0] wbs_bte_i; |
wire [wbs_dat_width-1:0] wbs_dat_o; |
wire wbs_ack_o; |
wire wbs_err_o; |
wire wbs_rty_o; |
|
|
// Slave select wire |
wire [wb_num_slaves-1:0] wb_slave_sel; |
|
// Slave out mux in wires |
wire [wbs_dat_width-1:0] wbs_dat_o_mux_i [0:wb_num_slaves-1]; |
wire wbs_ack_o_mux_i [0:wb_num_slaves-1]; |
wire wbs_err_o_mux_i [0:wb_num_slaves-1]; |
wire wbs_rty_o_mux_i [0:wb_num_slaves-1]; |
|
// Slave selects |
assign wb_slave_sel[0] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave0_adr; |
assign wb_slave_sel[1] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave1_adr; |
assign wb_slave_sel[2] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave2_adr; |
assign wb_slave_sel[3] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave3_adr; |
assign wb_slave_sel[4] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave4_adr; |
/* |
assign wb_slave_sel[5] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave5_adr; |
assign wb_slave_sel[6] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave6_adr; |
assign wb_slave_sel[7] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave7_adr; |
assign wb_slave_sel[8] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave8_adr; |
assign wb_slave_sel[9] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave9_adr; |
assign wb_slave_sel[10] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave10_adr; |
assign wb_slave_sel[11] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave11_adr; |
assign wb_slave_sel[12] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave12_adr; |
assign wb_slave_sel[13] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave13_adr; |
assign wb_slave_sel[14] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave14_adr; |
assign wb_slave_sel[15] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave15_adr; |
assign wb_slave_sel[16] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave16_adr; |
assign wb_slave_sel[16] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave17_adr; |
assign wb_slave_sel[16] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave18_adr; |
assign wb_slave_sel[16] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave19_adr; |
*/ |
|
|
// Assign master inputs to slaves and slave inputs for MUXing back to master |
|
// Slave 0 inputs |
assign wbs0_adr_i = wbm_adr_o; |
assign wbs0_dat_i = wbm_dat_o; |
assign wbs0_cyc_i = wbm_cyc_o & wb_slave_sel[0]; |
assign wbs0_stb_i = wbm_stb_o & wb_slave_sel[0]; |
assign wbs0_we_i = wbm_we_o; |
assign wbs0_cti_i = wbm_cti_o; |
assign wbs0_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[0] = wbs0_dat_o; |
assign wbs_ack_o_mux_i[0] = wbs0_ack_o & wb_slave_sel[0]; |
assign wbs_err_o_mux_i[0] = wbs0_err_o & wb_slave_sel[0]; |
assign wbs_rty_o_mux_i[0] = wbs0_rty_o & wb_slave_sel[0]; |
|
|
// Slave 1 inputs |
assign wbs1_adr_i = wbm_adr_o; |
assign wbs1_dat_i = wbm_dat_o; |
assign wbs1_cyc_i = wbm_cyc_o & wb_slave_sel[1]; |
assign wbs1_stb_i = wbm_stb_o & wb_slave_sel[1]; |
assign wbs1_we_i = wbm_we_o; |
assign wbs1_cti_i = wbm_cti_o; |
assign wbs1_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[1] = wbs1_dat_o; |
assign wbs_ack_o_mux_i[1] = wbs1_ack_o & wb_slave_sel[1]; |
assign wbs_err_o_mux_i[1] = wbs1_err_o & wb_slave_sel[1]; |
assign wbs_rty_o_mux_i[1] = wbs1_rty_o & wb_slave_sel[1]; |
|
|
// Slave 2 inputs |
assign wbs2_adr_i = wbm_adr_o; |
assign wbs2_dat_i = wbm_dat_o; |
assign wbs2_cyc_i = wbm_cyc_o & wb_slave_sel[2]; |
assign wbs2_stb_i = wbm_stb_o & wb_slave_sel[2]; |
assign wbs2_we_i = wbm_we_o; |
assign wbs2_cti_i = wbm_cti_o; |
assign wbs2_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[2] = wbs2_dat_o; |
assign wbs_ack_o_mux_i[2] = wbs2_ack_o & wb_slave_sel[2]; |
assign wbs_err_o_mux_i[2] = wbs2_err_o & wb_slave_sel[2]; |
assign wbs_rty_o_mux_i[2] = wbs2_rty_o & wb_slave_sel[2]; |
|
|
// Slave 3 inputs |
assign wbs3_adr_i = wbm_adr_o; |
assign wbs3_dat_i = wbm_dat_o; |
assign wbs3_cyc_i = wbm_cyc_o & wb_slave_sel[3]; |
assign wbs3_stb_i = wbm_stb_o & wb_slave_sel[3]; |
assign wbs3_we_i = wbm_we_o; |
assign wbs3_cti_i = wbm_cti_o; |
assign wbs3_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[3] = wbs3_dat_o; |
assign wbs_ack_o_mux_i[3] = wbs3_ack_o & wb_slave_sel[3]; |
assign wbs_err_o_mux_i[3] = wbs3_err_o & wb_slave_sel[3]; |
assign wbs_rty_o_mux_i[3] = wbs3_rty_o & wb_slave_sel[3]; |
|
|
// Slave 4 inputs |
assign wbs4_adr_i = wbm_adr_o; |
assign wbs4_dat_i = wbm_dat_o; |
assign wbs4_cyc_i = wbm_cyc_o & wb_slave_sel[4]; |
assign wbs4_stb_i = wbm_stb_o & wb_slave_sel[4]; |
assign wbs4_we_i = wbm_we_o; |
assign wbs4_cti_i = wbm_cti_o; |
assign wbs4_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[4] = wbs4_dat_o; |
assign wbs_ack_o_mux_i[4] = wbs4_ack_o & wb_slave_sel[4]; |
assign wbs_err_o_mux_i[4] = wbs4_err_o & wb_slave_sel[4]; |
assign wbs_rty_o_mux_i[4] = wbs4_rty_o & wb_slave_sel[4]; |
|
/* |
// Slave 5 inputs |
assign wbs5_adr_i = wbm_adr_o; |
assign wbs5_dat_i = wbm_dat_o; |
assign wbs5_cyc_i = wbm_cyc_o & wb_slave_sel[5]; |
assign wbs5_stb_i = wbm_stb_o & wb_slave_sel[5]; |
assign wbs5_we_i = wbm_we_o; |
assign wbs5_cti_i = wbm_cti_o; |
assign wbs5_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[5] = wbs5_dat_o; |
assign wbs_ack_o_mux_i[5] = wbs5_ack_o & wb_slave_sel[5]; |
assign wbs_err_o_mux_i[5] = wbs5_err_o & wb_slave_sel[5]; |
assign wbs_rty_o_mux_i[5] = wbs5_rty_o & wb_slave_sel[5]; |
|
|
// Slave 6 inputs |
assign wbs6_adr_i = wbm_adr_o; |
assign wbs6_dat_i = wbm_dat_o; |
assign wbs6_cyc_i = wbm_cyc_o & wb_slave_sel[6]; |
assign wbs6_stb_i = wbm_stb_o & wb_slave_sel[6]; |
assign wbs6_we_i = wbm_we_o; |
assign wbs6_cti_i = wbm_cti_o; |
assign wbs6_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[6] = wbs6_dat_o; |
assign wbs_ack_o_mux_i[6] = wbs6_ack_o & wb_slave_sel[6]; |
assign wbs_err_o_mux_i[6] = wbs6_err_o & wb_slave_sel[6]; |
assign wbs_rty_o_mux_i[6] = wbs6_rty_o & wb_slave_sel[6]; |
|
|
// Slave 7 inputs |
assign wbs7_adr_i = wbm_adr_o; |
assign wbs7_dat_i = wbm_dat_o; |
assign wbs7_cyc_i = wbm_cyc_o & wb_slave_sel[7]; |
assign wbs7_stb_i = wbm_stb_o & wb_slave_sel[7]; |
assign wbs7_we_i = wbm_we_o; |
assign wbs7_cti_i = wbm_cti_o; |
assign wbs7_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[7] = wbs7_dat_o; |
assign wbs_ack_o_mux_i[7] = wbs7_ack_o & wb_slave_sel[7]; |
assign wbs_err_o_mux_i[7] = wbs7_err_o & wb_slave_sel[7]; |
assign wbs_rty_o_mux_i[7] = wbs7_rty_o & wb_slave_sel[7]; |
|
|
// Slave 8 inputs |
assign wbs8_adr_i = wbm_adr_o; |
assign wbs8_dat_i = wbm_dat_o; |
assign wbs8_cyc_i = wbm_cyc_o & wb_slave_sel[8]; |
assign wbs8_stb_i = wbm_stb_o & wb_slave_sel[8]; |
assign wbs8_we_i = wbm_we_o; |
assign wbs8_cti_i = wbm_cti_o; |
assign wbs8_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[8] = wbs8_dat_o; |
assign wbs_ack_o_mux_i[8] = wbs8_ack_o & wb_slave_sel[8]; |
assign wbs_err_o_mux_i[8] = wbs8_err_o & wb_slave_sel[8]; |
assign wbs_rty_o_mux_i[8] = wbs8_rty_o & wb_slave_sel[8]; |
|
|
// Slave 9 inputs |
assign wbs9_adr_i = wbm_adr_o; |
assign wbs9_dat_i = wbm_dat_o; |
assign wbs9_cyc_i = wbm_cyc_o & wb_slave_sel[9]; |
assign wbs9_stb_i = wbm_stb_o & wb_slave_sel[9]; |
assign wbs9_we_i = wbm_we_o; |
assign wbs9_cti_i = wbm_cti_o; |
assign wbs9_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[9] = wbs9_dat_o; |
assign wbs_ack_o_mux_i[9] = wbs9_ack_o & wb_slave_sel[9]; |
assign wbs_err_o_mux_i[9] = wbs9_err_o & wb_slave_sel[9]; |
assign wbs_rty_o_mux_i[9] = wbs9_rty_o & wb_slave_sel[9]; |
|
|
// Slave 10 inputs |
assign wbs10_adr_i = wbm_adr_o; |
assign wbs10_dat_i = wbm_dat_o; |
assign wbs10_cyc_i = wbm_cyc_o & wb_slave_sel[10]; |
assign wbs10_stb_i = wbm_stb_o & wb_slave_sel[10]; |
assign wbs10_we_i = wbm_we_o; |
assign wbs10_cti_i = wbm_cti_o; |
assign wbs10_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[10] = wbs10_dat_o; |
assign wbs_ack_o_mux_i[10] = wbs10_ack_o & wb_slave_sel[10]; |
assign wbs_err_o_mux_i[10] = wbs10_err_o & wb_slave_sel[10]; |
assign wbs_rty_o_mux_i[10] = wbs10_rty_o & wb_slave_sel[10]; |
|
|
// Slave 11 inputs |
assign wbs11_adr_i = wbm_adr_o; |
assign wbs11_dat_i = wbm_dat_o; |
assign wbs11_cyc_i = wbm_cyc_o & wb_slave_sel[11]; |
assign wbs11_stb_i = wbm_stb_o & wb_slave_sel[11]; |
assign wbs11_we_i = wbm_we_o; |
assign wbs11_cti_i = wbm_cti_o; |
assign wbs11_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[11] = wbs11_dat_o; |
assign wbs_ack_o_mux_i[11] = wbs11_ack_o & wb_slave_sel[11]; |
assign wbs_err_o_mux_i[11] = wbs11_err_o & wb_slave_sel[11]; |
assign wbs_rty_o_mux_i[11] = wbs11_rty_o & wb_slave_sel[11]; |
|
// Slave 12 inputs |
assign wbs12_adr_i = wbm_adr_o; |
assign wbs12_dat_i = wbm_dat_o; |
assign wbs12_cyc_i = wbm_cyc_o & wb_slave_sel[12]; |
assign wbs12_stb_i = wbm_stb_o & wb_slave_sel[12]; |
assign wbs12_we_i = wbm_we_o; |
assign wbs12_cti_i = wbm_cti_o; |
assign wbs12_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[12] = wbs12_dat_o; |
assign wbs_ack_o_mux_i[12] = wbs12_ack_o & wb_slave_sel[12]; |
assign wbs_err_o_mux_i[12] = wbs12_err_o & wb_slave_sel[12]; |
assign wbs_rty_o_mux_i[12] = wbs12_rty_o & wb_slave_sel[12]; |
|
|
// Slave 13 inputs |
assign wbs13_adr_i = wbm_adr_o; |
assign wbs13_dat_i = wbm_dat_o; |
assign wbs13_cyc_i = wbm_cyc_o & wb_slave_sel[13]; |
assign wbs13_stb_i = wbm_stb_o & wb_slave_sel[13]; |
assign wbs13_we_i = wbm_we_o; |
assign wbs13_cti_i = wbm_cti_o; |
assign wbs13_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[13] = wbs13_dat_o; |
assign wbs_ack_o_mux_i[13] = wbs13_ack_o & wb_slave_sel[13]; |
assign wbs_err_o_mux_i[13] = wbs13_err_o & wb_slave_sel[13]; |
assign wbs_rty_o_mux_i[13] = wbs13_rty_o & wb_slave_sel[13]; |
|
|
// Slave 14 inputs |
assign wbs14_adr_i = wbm_adr_o; |
assign wbs14_dat_i = wbm_dat_o; |
assign wbs14_cyc_i = wbm_cyc_o & wb_slave_sel[14]; |
assign wbs14_stb_i = wbm_stb_o & wb_slave_sel[14]; |
assign wbs14_we_i = wbm_we_o; |
assign wbs14_cti_i = wbm_cti_o; |
assign wbs14_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[14] = wbs14_dat_o; |
assign wbs_ack_o_mux_i[14] = wbs14_ack_o & wb_slave_sel[14]; |
assign wbs_err_o_mux_i[14] = wbs14_err_o & wb_slave_sel[14]; |
assign wbs_rty_o_mux_i[14] = wbs14_rty_o & wb_slave_sel[14]; |
|
|
// Slave 15 inputs |
assign wbs15_adr_i = wbm_adr_o; |
assign wbs15_dat_i = wbm_dat_o; |
assign wbs15_cyc_i = wbm_cyc_o & wb_slave_sel[15]; |
assign wbs15_stb_i = wbm_stb_o & wb_slave_sel[15]; |
assign wbs15_we_i = wbm_we_o; |
assign wbs15_cti_i = wbm_cti_o; |
assign wbs15_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[15] = wbs15_dat_o; |
assign wbs_ack_o_mux_i[15] = wbs15_ack_o & wb_slave_sel[15]; |
assign wbs_err_o_mux_i[15] = wbs15_err_o & wb_slave_sel[15]; |
assign wbs_rty_o_mux_i[15] = wbs15_rty_o & wb_slave_sel[15]; |
|
|
// Slave 16 inputs |
assign wbs16_adr_i = wbm_adr_o; |
assign wbs16_dat_i = wbm_dat_o; |
assign wbs16_cyc_i = wbm_cyc_o & wb_slave_sel[16]; |
assign wbs16_stb_i = wbm_stb_o & wb_slave_sel[16]; |
assign wbs16_we_i = wbm_we_o; |
assign wbs16_cti_i = wbm_cti_o; |
assign wbs16_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[16] = wbs16_dat_o; |
assign wbs_ack_o_mux_i[16] = wbs16_ack_o & wb_slave_sel[16]; |
assign wbs_err_o_mux_i[16] = wbs16_err_o & wb_slave_sel[16]; |
assign wbs_rty_o_mux_i[16] = wbs16_rty_o & wb_slave_sel[16]; |
|
|
// Slave 17 inputs |
assign wbs17_adr_i = wbm_adr_o; |
assign wbs17_dat_i = wbm_dat_o; |
assign wbs17_cyc_i = wbm_cyc_o & wb_slave_sel[17]; |
assign wbs17_stb_i = wbm_stb_o & wb_slave_sel[17]; |
assign wbs17_we_i = wbm_we_o; |
assign wbs17_cti_i = wbm_cti_o; |
assign wbs17_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[17] = wbs17_dat_o; |
assign wbs_ack_o_mux_i[17] = wbs17_ack_o & wb_slave_sel[17]; |
assign wbs_err_o_mux_i[17] = wbs17_err_o & wb_slave_sel[17]; |
assign wbs_rty_o_mux_i[17] = wbs17_rty_o & wb_slave_sel[17]; |
|
// Slave 18 inputs |
assign wbs18_adr_i = wbm_adr_o; |
assign wbs18_dat_i = wbm_dat_o; |
assign wbs18_cyc_i = wbm_cyc_o & wb_slave_sel[18]; |
assign wbs18_stb_i = wbm_stb_o & wb_slave_sel[18]; |
assign wbs18_we_i = wbm_we_o; |
assign wbs18_cti_i = wbm_cti_o; |
assign wbs18_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[18] = wbs18_dat_o; |
assign wbs_ack_o_mux_i[18] = wbs18_ack_o & wb_slave_sel[18]; |
assign wbs_err_o_mux_i[18] = wbs18_err_o & wb_slave_sel[18]; |
assign wbs_rty_o_mux_i[18] = wbs18_rty_o & wb_slave_sel[18]; |
|
// Slave 19 inputs |
assign wbs19_adr_i = wbm_adr_o; |
assign wbs19_dat_i = wbm_dat_o; |
assign wbs19_cyc_i = wbm_cyc_o & wb_slave_sel[19]; |
assign wbs19_stb_i = wbm_stb_o & wb_slave_sel[19]; |
assign wbs19_we_i = wbm_we_o; |
assign wbs19_cti_i = wbm_cti_o; |
assign wbs19_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[19] = wbs19_dat_o; |
assign wbs_ack_o_mux_i[19] = wbs19_ack_o & wb_slave_sel[19]; |
assign wbs_err_o_mux_i[19] = wbs19_err_o & wb_slave_sel[19]; |
assign wbs_rty_o_mux_i[19] = wbs19_rty_o & wb_slave_sel[19]; |
|
*/ |
|
|
|
// Master out mux from slave in data |
assign wbm_dat_byte_i = wb_slave_sel[0] ? wbs_dat_o_mux_i[0] : |
wb_slave_sel[1] ? wbs_dat_o_mux_i[1] : |
wb_slave_sel[2] ? wbs_dat_o_mux_i[2] : |
wb_slave_sel[3] ? wbs_dat_o_mux_i[3] : |
wb_slave_sel[4] ? wbs_dat_o_mux_i[4] : |
/* |
wb_slave_sel[5] ? wbs_dat_o_mux_i[5] : |
wb_slave_sel[6] ? wbs_dat_o_mux_i[6] : |
wb_slave_sel[7] ? wbs_dat_o_mux_i[7] : |
wb_slave_sel[8] ? wbs_dat_o_mux_i[8] : |
wb_slave_sel[9] ? wbs_dat_o_mux_i[9] : |
wb_slave_sel[10] ? wbs_dat_o_mux_i[10] : |
wb_slave_sel[11] ? wbs_dat_o_mux_i[11] : |
wb_slave_sel[12] ? wbs_dat_o_mux_i[12] : |
wb_slave_sel[13] ? wbs_dat_o_mux_i[13] : |
wb_slave_sel[14] ? wbs_dat_o_mux_i[14] : |
wb_slave_sel[15] ? wbs_dat_o_mux_i[15] : |
wb_slave_sel[16] ? wbs_dat_o_mux_i[16] : |
wb_slave_sel[17] ? wbs_dat_o_mux_i[17] : |
wb_slave_sel[18] ? wbs_dat_o_mux_i[18] : |
wb_slave_sel[19] ? wbs_dat_o_mux_i[19] : |
*/ |
wbs_dat_o_mux_i[0]; |
// Master out acks, or together |
assign wbm_ack_i = wbs_ack_o_mux_i[0] | |
wbs_ack_o_mux_i[1] | |
wbs_ack_o_mux_i[2] | |
wbs_ack_o_mux_i[3] | |
wbs_ack_o_mux_i[4] /* | |
wbs_ack_o_mux_i[5] | |
wbs_ack_o_mux_i[6] | |
wbs_ack_o_mux_i[7] | |
wbs_ack_o_mux_i[8] | |
wbs_ack_o_mux_i[9] | |
wbs_ack_o_mux_i[10] | |
wbs_ack_o_mux_i[11] | |
wbs_ack_o_mux_i[12] | |
wbs_ack_o_mux_i[13] | |
wbs_ack_o_mux_i[14] | |
wbs_ack_o_mux_i[15] | |
wbs_ack_o_mux_i[16] | |
wbs_ack_o_mux_i[17] | |
wbs_ack_o_mux_i[18] | |
wbs_ack_o_mux_i[19] |
*/ |
; |
|
|
assign wbm_err_i = wbs_err_o_mux_i[0] | |
wbs_err_o_mux_i[1] | |
wbs_err_o_mux_i[2] | |
wbs_err_o_mux_i[3] | |
wbs_err_o_mux_i[4] |/* |
wbs_err_o_mux_i[5] | |
wbs_err_o_mux_i[6] | |
wbs_err_o_mux_i[7] | |
wbs_err_o_mux_i[8] | |
wbs_err_o_mux_i[9] | |
wbs_err_o_mux_i[10] | |
wbs_err_o_mux_i[11] | |
wbs_err_o_mux_i[12] | |
wbs_err_o_mux_i[13] | |
wbs_err_o_mux_i[14] | |
wbs_err_o_mux_i[15] | |
wbs_err_o_mux_i[16] | |
wbs_err_o_mux_i[17] | |
wbs_err_o_mux_i[18] | |
wbs_err_o_mux_i[19] | |
*/ |
watchdog_err ; |
|
|
assign wbm_rty_i = wbs_rty_o_mux_i[0] | |
wbs_rty_o_mux_i[1] | |
wbs_rty_o_mux_i[2] | |
wbs_rty_o_mux_i[3] | |
wbs_rty_o_mux_i[4] /*| |
wbs_rty_o_mux_i[5] | |
wbs_rty_o_mux_i[6] | |
wbs_rty_o_mux_i[7] | |
wbs_rty_o_mux_i[8] | |
wbs_rty_o_mux_i[9] | |
wbs_rty_o_mux_i[10] | |
wbs_rty_o_mux_i[11] | |
wbs_rty_o_mux_i[12] | |
wbs_rty_o_mux_i[13] | |
wbs_rty_o_mux_i[14] | |
wbs_rty_o_mux_i[15] | |
wbs_rty_o_mux_i[16] | |
wbs_rty_o_mux_i[17] | |
wbs_rty_o_mux_i[18] | |
wbs_rty_o_mux_i[19] |
*/ |
; |
|
endmodule // arbiter_bytebus |
/s3adsp1800/rtl/verilog/arbiter/arbiter_dbus.v
0,0 → 1,1268
////////////////////////////////////////////////////////////////////// |
/// //// |
/// Wishbone arbiter, burst-compatible //// |
/// //// |
/// Simple arbiter, multi-master, multi-slave with default slave //// |
/// for chaining with peripheral arbiter //// |
/// //// |
/// Julius Baxter, julius@opencores.org //// |
/// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009, 2010 Authors and 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
`include "orpsoc-defines.v" |
// 2 Masters, a few slaves |
module arbiter_dbus |
( |
// or1200 data master |
// Wishbone Master interface |
wbm0_adr_o, |
wbm0_dat_o, |
wbm0_sel_o, |
wbm0_we_o, |
wbm0_cyc_o, |
wbm0_stb_o, |
wbm0_cti_o, |
wbm0_bte_o, |
|
wbm0_dat_i, |
wbm0_ack_i, |
wbm0_err_i, |
wbm0_rty_i, |
|
// or1200 debug master |
// Wishbone Master interface |
wbm1_adr_o, |
wbm1_dat_o, |
wbm1_sel_o, |
wbm1_we_o, |
wbm1_cyc_o, |
wbm1_stb_o, |
wbm1_cti_o, |
wbm1_bte_o, |
|
wbm1_dat_i, |
wbm1_ack_i, |
wbm1_err_i, |
wbm1_rty_i, |
|
// Slave one |
// Wishbone Slave interface |
wbs0_adr_i, |
wbs0_dat_i, |
wbs0_sel_i, |
wbs0_we_i, |
wbs0_cyc_i, |
wbs0_stb_i, |
wbs0_cti_i, |
wbs0_bte_i, |
|
wbs0_dat_o, |
wbs0_ack_o, |
wbs0_err_o, |
wbs0_rty_o, |
|
// Slave two |
// Wishbone Slave interface |
wbs1_adr_i, |
wbs1_dat_i, |
wbs1_sel_i, |
wbs1_we_i, |
wbs1_cyc_i, |
wbs1_stb_i, |
wbs1_cti_i, |
wbs1_bte_i, |
|
wbs1_dat_o, |
wbs1_ack_o, |
wbs1_err_o, |
wbs1_rty_o, |
|
|
// Slave three |
// Wishbone Slave interface |
wbs2_adr_i, |
wbs2_dat_i, |
wbs2_sel_i, |
wbs2_we_i, |
wbs2_cyc_i, |
wbs2_stb_i, |
wbs2_cti_i, |
wbs2_bte_i, |
|
wbs2_dat_o, |
wbs2_ack_o, |
wbs2_err_o, |
wbs2_rty_o, |
/* |
// Slave four |
// Wishbone Slave interface |
wbs3_adr_i, |
wbs3_dat_i, |
wbs3_sel_i, |
wbs3_we_i, |
wbs3_cyc_i, |
wbs3_stb_i, |
wbs3_cti_i, |
wbs3_bte_i, |
|
wbs3_dat_o, |
wbs3_ack_o, |
wbs3_err_o, |
wbs3_rty_o, |
|
// Slave five |
// Wishbone Slave interface |
wbs4_adr_i, |
wbs4_dat_i, |
wbs4_sel_i, |
wbs4_we_i, |
wbs4_cyc_i, |
wbs4_stb_i, |
wbs4_cti_i, |
wbs4_bte_i, |
|
wbs4_dat_o, |
wbs4_ack_o, |
wbs4_err_o, |
wbs4_rty_o, |
|
// Slave six |
// Wishbone Slave interface |
wbs5_adr_i, |
wbs5_dat_i, |
wbs5_sel_i, |
wbs5_we_i, |
wbs5_cyc_i, |
wbs5_stb_i, |
wbs5_cti_i, |
wbs5_bte_i, |
|
wbs5_dat_o, |
wbs5_ack_o, |
wbs5_err_o, |
wbs5_rty_o, |
|
// Slave seven |
// Wishbone Slave interface |
wbs6_adr_i, |
wbs6_dat_i, |
wbs6_sel_i, |
wbs6_we_i, |
wbs6_cyc_i, |
wbs6_stb_i, |
wbs6_cti_i, |
wbs6_bte_i, |
|
wbs6_dat_o, |
wbs6_ack_o, |
wbs6_err_o, |
wbs6_rty_o, |
|
// Slave eight |
// Wishbone Slave interface |
wbs7_adr_i, |
wbs7_dat_i, |
wbs7_sel_i, |
wbs7_we_i, |
wbs7_cyc_i, |
wbs7_stb_i, |
wbs7_cti_i, |
wbs7_bte_i, |
|
wbs7_dat_o, |
wbs7_ack_o, |
wbs7_err_o, |
wbs7_rty_o, |
|
// Slave nine |
// Wishbone Slave interface |
wbs8_adr_i, |
wbs8_dat_i, |
wbs8_sel_i, |
wbs8_we_i, |
wbs8_cyc_i, |
wbs8_stb_i, |
wbs8_cti_i, |
wbs8_bte_i, |
|
wbs8_dat_o, |
wbs8_ack_o, |
wbs8_err_o, |
wbs8_rty_o, |
|
// Slave ten |
// Wishbone Slave interface |
wbs9_adr_i, |
wbs9_dat_i, |
wbs9_sel_i, |
wbs9_we_i, |
wbs9_cyc_i, |
wbs9_stb_i, |
wbs9_cti_i, |
wbs9_bte_i, |
|
wbs9_dat_o, |
wbs9_ack_o, |
wbs9_err_o, |
wbs9_rty_o, |
|
// Slave eleven |
// Wishbone Slave interface |
wbs10_adr_i, |
wbs10_dat_i, |
wbs10_sel_i, |
wbs10_we_i, |
wbs10_cyc_i, |
wbs10_stb_i, |
wbs10_cti_i, |
wbs10_bte_i, |
|
wbs10_dat_o, |
wbs10_ack_o, |
wbs10_err_o, |
wbs10_rty_o, |
|
// Slave twelve |
// Wishbone Slave interface |
wbs11_adr_i, |
wbs11_dat_i, |
wbs11_sel_i, |
wbs11_we_i, |
wbs11_cyc_i, |
wbs11_stb_i, |
wbs11_cti_i, |
wbs11_bte_i, |
|
wbs11_dat_o, |
wbs11_ack_o, |
wbs11_err_o, |
wbs11_rty_o, |
|
// Slave thirteen |
// Wishbone Slave interface |
wbs12_adr_i, |
wbs12_dat_i, |
wbs12_sel_i, |
wbs12_we_i, |
wbs12_cyc_i, |
wbs12_stb_i, |
wbs12_cti_i, |
wbs12_bte_i, |
|
wbs12_dat_o, |
wbs12_ack_o, |
wbs12_err_o, |
wbs12_rty_o, |
|
// Slave fourteen |
// Wishbone Slave interface |
wbs13_adr_i, |
wbs13_dat_i, |
wbs13_sel_i, |
wbs13_we_i, |
wbs13_cyc_i, |
wbs13_stb_i, |
wbs13_cti_i, |
wbs13_bte_i, |
|
wbs13_dat_o, |
wbs13_ack_o, |
wbs13_err_o, |
wbs13_rty_o, |
|
// Slave fifteen |
// Wishbone Slave interface |
wbs14_adr_i, |
wbs14_dat_i, |
wbs14_sel_i, |
wbs14_we_i, |
wbs14_cyc_i, |
wbs14_stb_i, |
wbs14_cti_i, |
wbs14_bte_i, |
|
wbs14_dat_o, |
wbs14_ack_o, |
wbs14_err_o, |
wbs14_rty_o, |
|
// Slave sixteen |
// Wishbone Slave interface |
wbs15_adr_i, |
wbs15_dat_i, |
wbs15_sel_i, |
wbs15_we_i, |
wbs15_cyc_i, |
wbs15_stb_i, |
wbs15_cti_i, |
wbs15_bte_i, |
|
wbs15_dat_o, |
wbs15_ack_o, |
wbs15_err_o, |
wbs15_rty_o, |
|
// Slave seventeen |
// Wishbone Slave interface |
wbs16_adr_i, |
wbs16_dat_i, |
wbs16_sel_i, |
wbs16_we_i, |
wbs16_cyc_i, |
wbs16_stb_i, |
wbs16_cti_i, |
wbs16_bte_i, |
|
wbs16_dat_o, |
wbs16_ack_o, |
wbs16_err_o, |
wbs16_rty_o, |
*/ |
|
wb_clk, |
wb_rst |
); |
|
parameter wb_dat_width = 32; |
parameter wb_adr_width = 32; |
|
parameter wb_addr_match_width = 8; |
|
parameter wb_num_slaves = 2; // must also (un)comment things if changing |
|
// Slave addresses - these should be defparam'd from top level |
// Declare them as you need them |
parameter slave0_adr = 0; |
parameter slave1_adr = 0; |
parameter slave2_adr = 0; |
parameter slave3_adr = 0; |
parameter slave4_adr = 0; |
parameter slave5_adr = 0; |
parameter slave6_adr = 0; |
parameter slave7_adr = 0; |
parameter slave8_adr = 0; |
parameter slave9_adr = 0; |
parameter slave10_adr = 0; |
parameter slave11_adr = 0; |
parameter slave12_adr = 0; |
|
// Select for slave 0 |
`define WB_ARB_ADDR_MATCH_SEL_SLAVE0 wb_adr_width-1:wb_adr_width-4 |
`define WB_ARB_ADDR_MATCH_SEL wb_adr_width-1:wb_adr_width-wb_addr_match_width |
|
input wb_clk; |
input wb_rst; |
|
// WB Master one |
input [wb_adr_width-1:0] wbm0_adr_o; |
input [wb_dat_width-1:0] wbm0_dat_o; |
input [3:0] wbm0_sel_o; |
input wbm0_we_o; |
input wbm0_cyc_o; |
input wbm0_stb_o; |
input [2:0] wbm0_cti_o; |
input [1:0] wbm0_bte_o; |
output [wb_dat_width-1:0] wbm0_dat_i; |
output wbm0_ack_i; |
output wbm0_err_i; |
output wbm0_rty_i; |
|
|
input [wb_adr_width-1:0] wbm1_adr_o; |
input [wb_dat_width-1:0] wbm1_dat_o; |
input [3:0] wbm1_sel_o; |
input wbm1_we_o; |
input wbm1_cyc_o; |
input wbm1_stb_o; |
input [2:0] wbm1_cti_o; |
input [1:0] wbm1_bte_o; |
output [wb_dat_width-1:0] wbm1_dat_i; |
output wbm1_ack_i; |
output wbm1_err_i; |
output wbm1_rty_i; |
|
|
// Slave one |
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs0_adr_i; |
output [wb_dat_width-1:0] wbs0_dat_i; |
output [3:0] wbs0_sel_i; |
output wbs0_we_i; |
output wbs0_cyc_i; |
output wbs0_stb_i; |
output [2:0] wbs0_cti_i; |
output [1:0] wbs0_bte_i; |
input [wb_dat_width-1:0] wbs0_dat_o; |
input wbs0_ack_o; |
input wbs0_err_o; |
input wbs0_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs1_adr_i; |
output [wb_dat_width-1:0] wbs1_dat_i; |
output [3:0] wbs1_sel_i; |
output wbs1_we_i; |
output wbs1_cyc_i; |
output wbs1_stb_i; |
output [2:0] wbs1_cti_i; |
output [1:0] wbs1_bte_i; |
input [wb_dat_width-1:0] wbs1_dat_o; |
input wbs1_ack_o; |
input wbs1_err_o; |
input wbs1_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs2_adr_i; |
output [wb_dat_width-1:0] wbs2_dat_i; |
output [3:0] wbs2_sel_i; |
output wbs2_we_i; |
output wbs2_cyc_i; |
output wbs2_stb_i; |
output [2:0] wbs2_cti_i; |
output [1:0] wbs2_bte_i; |
input [wb_dat_width-1:0] wbs2_dat_o; |
input wbs2_ack_o; |
input wbs2_err_o; |
input wbs2_rty_o; |
/* |
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs3_adr_i; |
output [wb_dat_width-1:0] wbs3_dat_i; |
output [3:0] wbs3_sel_i; |
output wbs3_we_i; |
output wbs3_cyc_i; |
output wbs3_stb_i; |
output [2:0] wbs3_cti_i; |
output [1:0] wbs3_bte_i; |
input [wb_dat_width-1:0] wbs3_dat_o; |
input wbs3_ack_o; |
input wbs3_err_o; |
input wbs3_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs4_adr_i; |
output [wb_dat_width-1:0] wbs4_dat_i; |
output [3:0] wbs4_sel_i; |
output wbs4_we_i; |
output wbs4_cyc_i; |
output wbs4_stb_i; |
output [2:0] wbs4_cti_i; |
output [1:0] wbs4_bte_i; |
input [wb_dat_width-1:0] wbs4_dat_o; |
input wbs4_ack_o; |
input wbs4_err_o; |
input wbs4_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs5_adr_i; |
output [wb_dat_width-1:0] wbs5_dat_i; |
output [3:0] wbs5_sel_i; |
output wbs5_we_i; |
output wbs5_cyc_i; |
output wbs5_stb_i; |
output [2:0] wbs5_cti_i; |
output [1:0] wbs5_bte_i; |
input [wb_dat_width-1:0] wbs5_dat_o; |
input wbs5_ack_o; |
input wbs5_err_o; |
input wbs5_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs6_adr_i; |
output [wb_dat_width-1:0] wbs6_dat_i; |
output [3:0] wbs6_sel_i; |
output wbs6_we_i; |
output wbs6_cyc_i; |
output wbs6_stb_i; |
output [2:0] wbs6_cti_i; |
output [1:0] wbs6_bte_i; |
input [wb_dat_width-1:0] wbs6_dat_o; |
input wbs6_ack_o; |
input wbs6_err_o; |
input wbs6_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs7_adr_i; |
output [wb_dat_width-1:0] wbs7_dat_i; |
output [3:0] wbs7_sel_i; |
output wbs7_we_i; |
output wbs7_cyc_i; |
output wbs7_stb_i; |
output [2:0] wbs7_cti_i; |
output [1:0] wbs7_bte_i; |
input [wb_dat_width-1:0] wbs7_dat_o; |
input wbs7_ack_o; |
input wbs7_err_o; |
input wbs7_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs8_adr_i; |
output [wb_dat_width-1:0] wbs8_dat_i; |
output [3:0] wbs8_sel_i; |
output wbs8_we_i; |
output wbs8_cyc_i; |
output wbs8_stb_i; |
output [2:0] wbs8_cti_i; |
output [1:0] wbs8_bte_i; |
input [wb_dat_width-1:0] wbs8_dat_o; |
input wbs8_ack_o; |
input wbs8_err_o; |
input wbs8_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs9_adr_i; |
output [wb_dat_width-1:0] wbs9_dat_i; |
output [3:0] wbs9_sel_i; |
output wbs9_we_i; |
output wbs9_cyc_i; |
output wbs9_stb_i; |
output [2:0] wbs9_cti_i; |
output [1:0] wbs9_bte_i; |
input [wb_dat_width-1:0] wbs9_dat_o; |
input wbs9_ack_o; |
input wbs9_err_o; |
input wbs9_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs10_adr_i; |
output [wb_dat_width-1:0] wbs10_dat_i; |
output [3:0] wbs10_sel_i; |
output wbs10_we_i; |
output wbs10_cyc_i; |
output wbs10_stb_i; |
output [2:0] wbs10_cti_i; |
output [1:0] wbs10_bte_i; |
input [wb_dat_width-1:0] wbs10_dat_o; |
input wbs10_ack_o; |
input wbs10_err_o; |
input wbs10_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs11_adr_i; |
output [wb_dat_width-1:0] wbs11_dat_i; |
output [3:0] wbs11_sel_i; |
output wbs11_we_i; |
output wbs11_cyc_i; |
output wbs11_stb_i; |
output [2:0] wbs11_cti_i; |
output [1:0] wbs11_bte_i; |
input [wb_dat_width-1:0] wbs11_dat_o; |
input wbs11_ack_o; |
input wbs11_err_o; |
input wbs11_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs12_adr_i; |
output [wb_dat_width-1:0] wbs12_dat_i; |
output [3:0] wbs12_sel_i; |
output wbs12_we_i; |
output wbs12_cyc_i; |
output wbs12_stb_i; |
output [2:0] wbs12_cti_i; |
output [1:0] wbs12_bte_i; |
input [wb_dat_width-1:0] wbs12_dat_o; |
input wbs12_ack_o; |
input wbs12_err_o; |
input wbs12_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs13_adr_i; |
output [wb_dat_width-1:0] wbs13_dat_i; |
output [3:0] wbs13_sel_i; |
output wbs13_we_i; |
output wbs13_cyc_i; |
output wbs13_stb_i; |
output [2:0] wbs13_cti_i; |
output [1:0] wbs13_bte_i; |
input [wb_dat_width-1:0] wbs13_dat_o; |
input wbs13_ack_o; |
input wbs13_err_o; |
input wbs13_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs14_adr_i; |
output [wb_dat_width-1:0] wbs14_dat_i; |
output [3:0] wbs14_sel_i; |
output wbs14_we_i; |
output wbs14_cyc_i; |
output wbs14_stb_i; |
output [2:0] wbs14_cti_i; |
output [1:0] wbs14_bte_i; |
input [wb_dat_width-1:0] wbs14_dat_o; |
input wbs14_ack_o; |
input wbs14_err_o; |
input wbs14_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs15_adr_i; |
output [wb_dat_width-1:0] wbs15_dat_i; |
output [3:0] wbs15_sel_i; |
output wbs15_we_i; |
output wbs15_cyc_i; |
output wbs15_stb_i; |
output [2:0] wbs15_cti_i; |
output [1:0] wbs15_bte_i; |
input [wb_dat_width-1:0] wbs15_dat_o; |
input wbs15_ack_o; |
input wbs15_err_o; |
input wbs15_rty_o; |
|
|
// Wishbone Slave interface |
output [wb_adr_width-1:0] wbs16_adr_i; |
output [wb_dat_width-1:0] wbs16_dat_i; |
output [3:0] wbs16_sel_i; |
output wbs16_we_i; |
output wbs16_cyc_i; |
output wbs16_stb_i; |
output [2:0] wbs16_cti_i; |
output [1:0] wbs16_bte_i; |
input [wb_dat_width-1:0] wbs16_dat_o; |
input wbs16_ack_o; |
input wbs16_err_o; |
input wbs16_rty_o; |
|
*/ |
|
reg watchdog_err; |
|
`ifdef ARBITER_DBUS_REGISTERING |
|
|
// Registering setup: |
// Masters typically register their outputs, so do the master selection and |
// muxing before registering in the arbiter. Keep the common parts outside |
// for code brevity. |
|
// Master ins -> |MUX> -> these wires |
wire [wb_adr_width-1:0] wbm_adr_o_w; |
wire [wb_dat_width-1:0] wbm_dat_o_w; |
wire [3:0] wbm_sel_o_w; |
wire wbm_we_o_w; |
wire wbm_cyc_o_w; |
wire wbm_stb_o_w; |
wire [2:0] wbm_cti_o_w; |
wire [1:0] wbm_bte_o_w; |
// Slave ins -> |MUX> -> these wires |
wire [wb_dat_width-1:0] wbm_dat_i; |
wire wbm_ack_i; |
wire wbm_err_i; |
wire wbm_rty_i; |
|
// Registers after masters input mux |
reg [wb_adr_width-1:0] wbm_adr_o_r; |
reg [wb_dat_width-1:0] wbm_dat_o_r; |
reg [3:0] wbm_sel_o_r; |
reg wbm_we_o_r; |
reg wbm_cyc_o_r; |
reg wbm_stb_o_r; |
reg [2:0] wbm_cti_o_r; |
reg [1:0] wbm_bte_o_r; |
|
// Master input mux register wires |
wire [wb_adr_width-1:0] wbm_adr_o; |
wire [wb_dat_width-1:0] wbm_dat_o; |
wire [3:0] wbm_sel_o; |
wire wbm_we_o; |
wire wbm_cyc_o; |
wire wbm_stb_o; |
wire [2:0] wbm_cti_o; |
wire [1:0] wbm_bte_o; |
|
// Registers after slaves input mux |
reg [wb_dat_width-1:0] wbm_dat_i_r; |
reg wbm_ack_i_r; |
reg wbm_err_i_r; |
reg wbm_rty_i_r; |
|
// Master select (MUX controls) |
wire [1:0] master_sel; |
// priority to wbm1, the debug master |
assign master_sel[0] = wbm0_cyc_o & !wbm1_cyc_o; |
assign master_sel[1] = wbm1_cyc_o; |
|
|
// Master input mux, priority to debug master |
assign wbm_adr_o_w = master_sel[1] ? wbm1_adr_o : |
wbm0_adr_o; |
|
assign wbm_dat_o_w = master_sel[1] ? wbm1_dat_o : |
wbm0_dat_o; |
|
assign wbm_sel_o_w = master_sel[1] ? wbm1_sel_o : |
wbm0_sel_o; |
|
assign wbm_we_o_w = master_sel[1] ? wbm1_we_o : |
wbm0_we_o; |
|
assign wbm_cyc_o_w = master_sel[1] ? wbm1_cyc_o : |
wbm0_cyc_o; |
|
assign wbm_stb_o_w = master_sel[1] ? wbm1_stb_o : |
wbm0_stb_o; |
|
assign wbm_cti_o_w = master_sel[1] ? wbm1_cti_o : |
wbm0_cti_o; |
|
assign wbm_bte_o_w = master_sel[1] ? wbm1_bte_o : |
wbm0_bte_o; |
|
|
// Register muxed master signals |
always @(posedge wb_clk) |
begin |
wbm_adr_o_r <= wbm_adr_o_w; |
wbm_dat_o_r <= wbm_dat_o_w; |
wbm_sel_o_r <= wbm_sel_o_w; |
wbm_we_o_r <= wbm_we_o_w; |
wbm_cyc_o_r <= wbm_cyc_o_w; |
wbm_stb_o_r <= wbm_stb_o_w & !wbm_ack_i & !wbm_ack_i_r; |
wbm_cti_o_r <= wbm_cti_o_w; |
wbm_bte_o_r <= wbm_bte_o_w; |
|
wbm_dat_i_r <= wbm_dat_i; |
wbm_ack_i_r <= wbm_ack_i; |
wbm_err_i_r <= wbm_err_i; |
wbm_rty_i_r <= wbm_rty_i; |
end // always @ (posedge wb_clk) |
|
|
assign wbm_adr_o = wbm_adr_o_r; |
assign wbm_dat_o = wbm_dat_o_r; |
assign wbm_sel_o = wbm_sel_o_r; |
assign wbm_we_o = wbm_we_o_r; |
assign wbm_cyc_o = wbm_cyc_o_r; |
assign wbm_stb_o = wbm_stb_o_r; |
assign wbm_cti_o = wbm_cti_o_r; |
assign wbm_bte_o = wbm_bte_o_r; |
|
// Master input mux, priority to debug master |
assign wbm0_dat_i = wbm_dat_i_r; |
assign wbm0_ack_i = wbm_ack_i_r & master_sel[0]; |
assign wbm0_err_i = wbm_err_i_r & master_sel[0]; |
assign wbm0_rty_i = wbm_rty_i_r & master_sel[0]; |
|
assign wbm1_dat_i = wbm_dat_i_r; |
assign wbm1_ack_i = wbm_ack_i_r & master_sel[1]; |
assign wbm1_err_i = wbm_err_i_r & master_sel[1]; |
assign wbm1_rty_i = wbm_rty_i_r & master_sel[1]; |
|
`else // !`ifdef ARBITER_DBUS_REGISTERING |
|
// Master input mux output wires |
wire [wb_adr_width-1:0] wbm_adr_o; |
wire [wb_dat_width-1:0] wbm_dat_o; |
wire [3:0] wbm_sel_o; |
wire wbm_we_o; |
wire wbm_cyc_o; |
wire wbm_stb_o; |
wire [2:0] wbm_cti_o; |
wire [1:0] wbm_bte_o; |
|
// Master select |
wire [1:0] master_sel; |
// priority to wbm1, the debug master |
assign master_sel[0] = wbm0_cyc_o & !wbm1_cyc_o; |
assign master_sel[1] = wbm1_cyc_o; |
|
|
// Master input mux, priority to debug master |
assign wbm_adr_o = master_sel[1] ? wbm1_adr_o : |
wbm0_adr_o; |
|
assign wbm_dat_o = master_sel[1] ? wbm1_dat_o : |
wbm0_dat_o; |
|
assign wbm_sel_o = master_sel[1] ? wbm1_sel_o : |
wbm0_sel_o; |
|
assign wbm_we_o = master_sel[1] ? wbm1_we_o : |
wbm0_we_o; |
|
assign wbm_cyc_o = master_sel[1] ? wbm1_cyc_o : |
wbm0_cyc_o; |
|
assign wbm_stb_o = master_sel[1] ? wbm1_stb_o : |
wbm0_stb_o; |
|
assign wbm_cti_o = master_sel[1] ? wbm1_cti_o : |
wbm0_cti_o; |
|
assign wbm_bte_o = master_sel[1] ? wbm1_bte_o : |
wbm0_bte_o; |
|
|
wire [wb_dat_width-1:0] wbm_dat_i; |
wire wbm_ack_i; |
wire wbm_err_i; |
wire wbm_rty_i; |
|
|
assign wbm0_dat_i = wbm_dat_i; |
assign wbm0_ack_i = wbm_ack_i & master_sel[0]; |
assign wbm0_err_i = wbm_err_i & master_sel[0]; |
assign wbm0_rty_i = wbm_rty_i & master_sel[0]; |
|
assign wbm1_dat_i = wbm_dat_i; |
assign wbm1_ack_i = wbm_ack_i & master_sel[1]; |
assign wbm1_err_i = wbm_err_i & master_sel[1]; |
assign wbm1_rty_i = wbm_rty_i & master_sel[1]; |
|
|
|
`endif // !`ifdef ARBITER_DBUS_REGISTERING |
|
|
// Slave select wire |
wire [wb_num_slaves-1:0] wb_slave_sel; |
reg [wb_num_slaves-1:0] wb_slave_sel_r; |
|
// Register wb_slave_sel_r to break combinatorial loop when selecting default |
// slave |
always @(posedge wb_clk) |
wb_slave_sel_r <= wb_slave_sel; |
|
// Slave out mux in wires |
wire [wb_dat_width-1:0] wbs_dat_o_mux_i [0:wb_num_slaves-1]; |
wire wbs_ack_o_mux_i [0:wb_num_slaves-1]; |
wire wbs_err_o_mux_i [0:wb_num_slaves-1]; |
wire wbs_rty_o_mux_i [0:wb_num_slaves-1]; |
|
// |
// Slave selects |
// |
assign wb_slave_sel[0] = wbm_adr_o[31:28] == slave0_adr | wbm_adr_o[31:28] == 4'hf; // Special case, point all reads to ROM address to here |
assign wb_slave_sel[1] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave1_adr; |
|
// Auto select last slave when others are not selected |
assign wb_slave_sel[2] = !(wb_slave_sel_r[0] | wb_slave_sel_r[1]); |
|
/* |
assign wb_slave_sel[2] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave2_adr; |
assign wb_slave_sel[3] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave3_adr; |
assign wb_slave_sel[4] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave4_adr; |
assign wb_slave_sel[5] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave5_adr; |
assign wb_slave_sel[6] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave6_adr; |
assign wb_slave_sel[7] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave7_adr; |
assign wb_slave_sel[8] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave8_adr; |
assign wb_slave_sel[9] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave9_adr; |
assign wb_slave_sel[10] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave10_adr; |
assign wb_slave_sel[11] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave11_adr; |
assign wb_slave_sel[12] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave12_adr; |
assign wb_slave_sel[13] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave13_adr; |
assign wb_slave_sel[14] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave14_adr; |
assign wb_slave_sel[15] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave15_adr; |
assign wb_slave_sel[16] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == slave16_adr; |
*/ |
|
`ifdef ARBITER_DBUS_WATCHDOG |
reg [`ARBITER_DBUS_WATCHDOG_TIMER_WIDTH:0] watchdog_timer; |
reg wbm_stb_r; // Register strobe |
wire wbm_stb_edge; // Detect its edge |
|
always @(posedge wb_clk) |
wbm_stb_r <= wbm_stb_o; |
|
assign wbm_stb_edge = (wbm_stb_o & !wbm_stb_r); |
|
// Counter logic |
always @(posedge wb_clk) |
if (wb_rst) watchdog_timer <= 0; |
else if (wbm_ack_i) // When we see an ack, turn off timer |
watchdog_timer <= 0; |
else if (wbm_stb_edge) // New access means start timer again |
watchdog_timer <= 1; |
else if (|watchdog_timer) // Continue counting if counter > 0 |
watchdog_timer <= watchdog_timer + 1; |
|
always @(posedge wb_clk) |
watchdog_err <= (&watchdog_timer); |
|
|
`else // !`ifdef ARBITER_DBUS_WATCHDOG |
|
always @(posedge wb_clk) |
watchdog_err <= 0; |
|
`endif // !`ifdef ARBITER_DBUS_WATCHDOG |
|
|
|
// Slave 0 inputs |
assign wbs0_adr_i = wbm_adr_o; |
assign wbs0_dat_i = wbm_dat_o; |
assign wbs0_sel_i = wbm_sel_o; |
assign wbs0_cyc_i = wbm_cyc_o & wb_slave_sel_r[0]; |
assign wbs0_stb_i = wbm_stb_o & wb_slave_sel_r[0]; |
assign wbs0_we_i = wbm_we_o; |
assign wbs0_cti_i = wbm_cti_o; |
assign wbs0_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[0] = wbs0_dat_o; |
assign wbs_ack_o_mux_i[0] = wbs0_ack_o & wb_slave_sel_r[0]; |
assign wbs_err_o_mux_i[0] = wbs0_err_o & wb_slave_sel_r[0]; |
assign wbs_rty_o_mux_i[0] = wbs0_rty_o & wb_slave_sel_r[0]; |
|
|
// Slave 1 inputs |
assign wbs1_adr_i = wbm_adr_o; |
assign wbs1_dat_i = wbm_dat_o; |
assign wbs1_sel_i = wbm_sel_o; |
assign wbs1_cyc_i = wbm_cyc_o & wb_slave_sel_r[1]; |
assign wbs1_stb_i = wbm_stb_o & wb_slave_sel_r[1]; |
assign wbs1_we_i = wbm_we_o; |
assign wbs1_cti_i = wbm_cti_o; |
assign wbs1_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[1] = wbs1_dat_o; |
assign wbs_ack_o_mux_i[1] = wbs1_ack_o & wb_slave_sel_r[1]; |
assign wbs_err_o_mux_i[1] = wbs1_err_o & wb_slave_sel_r[1]; |
assign wbs_rty_o_mux_i[1] = wbs1_rty_o & wb_slave_sel_r[1]; |
|
|
// Slave 2 inputs |
assign wbs2_adr_i = wbm_adr_o; |
assign wbs2_dat_i = wbm_dat_o; |
assign wbs2_sel_i = wbm_sel_o; |
assign wbs2_cyc_i = wbm_cyc_o & wb_slave_sel_r[2]; |
assign wbs2_stb_i = wbm_stb_o & wb_slave_sel_r[2]; |
assign wbs2_we_i = wbm_we_o; |
assign wbs2_cti_i = wbm_cti_o; |
assign wbs2_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[2] = wbs2_dat_o; |
assign wbs_ack_o_mux_i[2] = wbs2_ack_o & wb_slave_sel_r[2]; |
assign wbs_err_o_mux_i[2] = wbs2_err_o & wb_slave_sel_r[2]; |
assign wbs_rty_o_mux_i[2] = wbs2_rty_o & wb_slave_sel_r[2]; |
/* |
|
// Slave 3 inputs |
assign wbs3_adr_i = wbm_adr_o; |
assign wbs3_dat_i = wbm_dat_o; |
assign wbs3_sel_i = wbm_sel_o; |
assign wbs3_cyc_i = wbm_cyc_o & wb_slave_sel_r[3]; |
assign wbs3_stb_i = wbm_stb_o & wb_slave_sel_r[3]; |
assign wbs3_we_i = wbm_we_o; |
assign wbs3_cti_i = wbm_cti_o; |
assign wbs3_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[3] = wbs3_dat_o; |
assign wbs_ack_o_mux_i[3] = wbs3_ack_o & wb_slave_sel_r[3]; |
assign wbs_err_o_mux_i[3] = wbs3_err_o & wb_slave_sel_r[3]; |
assign wbs_rty_o_mux_i[3] = wbs3_rty_o & wb_slave_sel_r[3]; |
|
// Slave 4 inputs |
assign wbs4_adr_i = wbm_adr_o; |
assign wbs4_dat_i = wbm_dat_o; |
assign wbs4_sel_i = wbm_sel_o; |
assign wbs4_cyc_i = wbm_cyc_o & wb_slave_sel_r[4]; |
assign wbs4_stb_i = wbm_stb_o & wb_slave_sel_r[4]; |
assign wbs4_we_i = wbm_we_o; |
assign wbs4_cti_i = wbm_cti_o; |
assign wbs4_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[4] = wbs4_dat_o; |
assign wbs_ack_o_mux_i[4] = wbs4_ack_o & wb_slave_sel_r[4]; |
assign wbs_err_o_mux_i[4] = wbs4_err_o & wb_slave_sel_r[4]; |
assign wbs_rty_o_mux_i[4] = wbs4_rty_o & wb_slave_sel_r[4]; |
|
|
// Slave 5 inputs |
assign wbs5_adr_i = wbm_adr_o; |
assign wbs5_dat_i = wbm_dat_o; |
assign wbs5_sel_i = wbm_sel_o; |
assign wbs5_cyc_i = wbm_cyc_o & wb_slave_sel_r[5]; |
assign wbs5_stb_i = wbm_stb_o & wb_slave_sel_r[5]; |
assign wbs5_we_i = wbm_we_o; |
assign wbs5_cti_i = wbm_cti_o; |
assign wbs5_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[5] = wbs5_dat_o; |
assign wbs_ack_o_mux_i[5] = wbs5_ack_o & wb_slave_sel_r[5]; |
assign wbs_err_o_mux_i[5] = wbs5_err_o & wb_slave_sel_r[5]; |
assign wbs_rty_o_mux_i[5] = wbs5_rty_o & wb_slave_sel_r[5]; |
|
|
// Slave 6 inputs |
assign wbs6_adr_i = wbm_adr_o; |
assign wbs6_dat_i = wbm_dat_o; |
assign wbs6_sel_i = wbm_sel_o; |
assign wbs6_cyc_i = wbm_cyc_o & wb_slave_sel_r[6]; |
assign wbs6_stb_i = wbm_stb_o & wb_slave_sel_r[6]; |
assign wbs6_we_i = wbm_we_o; |
assign wbs6_cti_i = wbm_cti_o; |
assign wbs6_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[6] = wbs6_dat_o; |
assign wbs_ack_o_mux_i[6] = wbs6_ack_o & wb_slave_sel_r[6]; |
assign wbs_err_o_mux_i[6] = wbs6_err_o & wb_slave_sel_r[6]; |
assign wbs_rty_o_mux_i[6] = wbs6_rty_o & wb_slave_sel_r[6]; |
|
|
// Slave 7 inputs |
assign wbs7_adr_i = wbm_adr_o; |
assign wbs7_dat_i = wbm_dat_o; |
assign wbs7_sel_i = wbm_sel_o; |
assign wbs7_cyc_i = wbm_cyc_o & wb_slave_sel_r[7]; |
assign wbs7_stb_i = wbm_stb_o & wb_slave_sel_r[7]; |
assign wbs7_we_i = wbm_we_o; |
assign wbs7_cti_i = wbm_cti_o; |
assign wbs7_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[7] = wbs7_dat_o; |
assign wbs_ack_o_mux_i[7] = wbs7_ack_o & wb_slave_sel_r[7]; |
assign wbs_err_o_mux_i[7] = wbs7_err_o & wb_slave_sel_r[7]; |
assign wbs_rty_o_mux_i[7] = wbs7_rty_o & wb_slave_sel_r[7]; |
|
|
// Slave 8 inputs |
assign wbs8_adr_i = wbm_adr_o; |
assign wbs8_dat_i = wbm_dat_o; |
assign wbs8_sel_i = wbm_sel_o; |
assign wbs8_cyc_i = wbm_cyc_o & wb_slave_sel_r[8]; |
assign wbs8_stb_i = wbm_stb_o & wb_slave_sel_r[8]; |
assign wbs8_we_i = wbm_we_o; |
assign wbs8_cti_i = wbm_cti_o; |
assign wbs8_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[8] = wbs8_dat_o; |
assign wbs_ack_o_mux_i[8] = wbs8_ack_o & wb_slave_sel_r[8]; |
assign wbs_err_o_mux_i[8] = wbs8_err_o & wb_slave_sel_r[8]; |
assign wbs_rty_o_mux_i[8] = wbs8_rty_o & wb_slave_sel_r[8]; |
|
|
// Slave 9 inputs |
assign wbs9_adr_i = wbm_adr_o; |
assign wbs9_dat_i = wbm_dat_o; |
assign wbs9_sel_i = wbm_sel_o; |
assign wbs9_cyc_i = wbm_cyc_o & wb_slave_sel_r[9]; |
assign wbs9_stb_i = wbm_stb_o & wb_slave_sel_r[9]; |
assign wbs9_we_i = wbm_we_o; |
assign wbs9_cti_i = wbm_cti_o; |
assign wbs9_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[9] = wbs9_dat_o; |
assign wbs_ack_o_mux_i[9] = wbs9_ack_o & wb_slave_sel_r[9]; |
assign wbs_err_o_mux_i[9] = wbs9_err_o & wb_slave_sel_r[9]; |
assign wbs_rty_o_mux_i[9] = wbs9_rty_o & wb_slave_sel_r[9]; |
|
|
// Slave 10 inputs |
assign wbs10_adr_i = wbm_adr_o; |
assign wbs10_dat_i = wbm_dat_o; |
assign wbs10_sel_i = wbm_sel_o; |
assign wbs10_cyc_i = wbm_cyc_o & wb_slave_sel_r[10]; |
assign wbs10_stb_i = wbm_stb_o & wb_slave_sel_r[10]; |
assign wbs10_we_i = wbm_we_o; |
assign wbs10_cti_i = wbm_cti_o; |
assign wbs10_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[10] = wbs10_dat_o; |
assign wbs_ack_o_mux_i[10] = wbs10_ack_o & wb_slave_sel_r[10]; |
assign wbs_err_o_mux_i[10] = wbs10_err_o & wb_slave_sel_r[10]; |
assign wbs_rty_o_mux_i[10] = wbs10_rty_o & wb_slave_sel_r[10]; |
|
|
// Slave 11 inputs |
assign wbs11_adr_i = wbm_adr_o; |
assign wbs11_dat_i = wbm_dat_o; |
assign wbs11_sel_i = wbm_sel_o; |
assign wbs11_cyc_i = wbm_cyc_o & wb_slave_sel_r[11]; |
assign wbs11_stb_i = wbm_stb_o & wb_slave_sel_r[11]; |
assign wbs11_we_i = wbm_we_o; |
assign wbs11_cti_i = wbm_cti_o; |
assign wbs11_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[11] = wbs11_dat_o; |
assign wbs_ack_o_mux_i[11] = wbs11_ack_o & wb_slave_sel_r[11]; |
assign wbs_err_o_mux_i[11] = wbs11_err_o & wb_slave_sel_r[11]; |
assign wbs_rty_o_mux_i[11] = wbs11_rty_o & wb_slave_sel_r[11]; |
|
|
// Slave 12 inputs |
assign wbs12_adr_i = wbm_adr_o; |
assign wbs12_dat_i = wbm_dat_o; |
assign wbs12_sel_i = wbm_sel_o; |
assign wbs12_cyc_i = wbm_cyc_o & wb_slave_sel_r[12]; |
assign wbs12_stb_i = wbm_stb_o & wb_slave_sel_r[12]; |
assign wbs12_we_i = wbm_we_o; |
assign wbs12_cti_i = wbm_cti_o; |
assign wbs12_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[12] = wbs12_dat_o; |
assign wbs_ack_o_mux_i[12] = wbs12_ack_o & wb_slave_sel_r[12]; |
assign wbs_err_o_mux_i[12] = wbs12_err_o & wb_slave_sel_r[12]; |
assign wbs_rty_o_mux_i[12] = wbs12_rty_o & wb_slave_sel_r[12]; |
|
|
// Slave 13 inputs |
assign wbs13_adr_i = wbm_adr_o; |
assign wbs13_dat_i = wbm_dat_o; |
assign wbs13_sel_i = wbm_sel_o; |
assign wbs13_cyc_i = wbm_cyc_o & wb_slave_sel_r[13]; |
assign wbs13_stb_i = wbm_stb_o & wb_slave_sel_r[13]; |
assign wbs13_we_i = wbm_we_o; |
assign wbs13_cti_i = wbm_cti_o; |
assign wbs13_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[13] = wbs13_dat_o; |
assign wbs_ack_o_mux_i[13] = wbs13_ack_o & wb_slave_sel_r[13]; |
assign wbs_err_o_mux_i[13] = wbs13_err_o & wb_slave_sel_r[13]; |
assign wbs_rty_o_mux_i[13] = wbs13_rty_o & wb_slave_sel_r[13]; |
|
|
// Slave 14 inputs |
assign wbs14_adr_i = wbm_adr_o; |
assign wbs14_dat_i = wbm_dat_o; |
assign wbs14_sel_i = wbm_sel_o; |
assign wbs14_cyc_i = wbm_cyc_o & wb_slave_sel_r[14]; |
assign wbs14_stb_i = wbm_stb_o & wb_slave_sel_r[14]; |
assign wbs14_we_i = wbm_we_o; |
assign wbs14_cti_i = wbm_cti_o; |
assign wbs14_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[14] = wbs14_dat_o; |
assign wbs_ack_o_mux_i[14] = wbs14_ack_o & wb_slave_sel_r[14]; |
assign wbs_err_o_mux_i[14] = wbs14_err_o & wb_slave_sel_r[14]; |
assign wbs_rty_o_mux_i[14] = wbs14_rty_o & wb_slave_sel_r[14]; |
|
|
// Slave 15 inputs |
assign wbs15_adr_i = wbm_adr_o; |
assign wbs15_dat_i = wbm_dat_o; |
assign wbs15_sel_i = wbm_sel_o; |
assign wbs15_cyc_i = wbm_cyc_o & wb_slave_sel_r[15]; |
assign wbs15_stb_i = wbm_stb_o & wb_slave_sel_r[15]; |
assign wbs15_we_i = wbm_we_o; |
assign wbs15_cti_i = wbm_cti_o; |
assign wbs15_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[15] = wbs15_dat_o; |
assign wbs_ack_o_mux_i[15] = wbs15_ack_o & wb_slave_sel_r[15]; |
assign wbs_err_o_mux_i[15] = wbs15_err_o & wb_slave_sel_r[15]; |
assign wbs_rty_o_mux_i[15] = wbs15_rty_o & wb_slave_sel_r[15]; |
|
|
// Slave 16 inputs |
assign wbs16_adr_i = wbm_adr_o; |
assign wbs16_dat_i = wbm_dat_o; |
assign wbs16_sel_i = wbm_sel_o; |
assign wbs16_cyc_i = wbm_cyc_o & wb_slave_sel_r[16]; |
assign wbs16_stb_i = wbm_stb_o & wb_slave_sel_r[16]; |
assign wbs16_we_i = wbm_we_o; |
assign wbs16_cti_i = wbm_cti_o; |
assign wbs16_bte_i = wbm_bte_o; |
assign wbs_dat_o_mux_i[16] = wbs16_dat_o; |
assign wbs_ack_o_mux_i[16] = wbs16_ack_o & wb_slave_sel_r[16]; |
assign wbs_err_o_mux_i[16] = wbs16_err_o & wb_slave_sel_r[16]; |
assign wbs_rty_o_mux_i[16] = wbs16_rty_o & wb_slave_sel_r[16]; |
|
*/ |
|
|
|
// Master out mux from slave in data |
assign wbm_dat_i = wb_slave_sel_r[0] ? wbs_dat_o_mux_i[0] : |
wb_slave_sel_r[1] ? wbs_dat_o_mux_i[1] : |
wb_slave_sel_r[2] ? wbs_dat_o_mux_i[2] : |
/* wb_slave_sel_r[3] ? wbs_dat_o_mux_i[3] : |
wb_slave_sel_r[4] ? wbs_dat_o_mux_i[4] : |
wb_slave_sel_r[5] ? wbs_dat_o_mux_i[5] : |
wb_slave_sel_r[6] ? wbs_dat_o_mux_i[6] : |
wb_slave_sel_r[7] ? wbs_dat_o_mux_i[7] : |
wb_slave_sel_r[8] ? wbs_dat_o_mux_i[8] : |
wb_slave_sel_r[9] ? wbs_dat_o_mux_i[9] : |
wb_slave_sel_r[10] ? wbs_dat_o_mux_i[10] : |
wb_slave_sel_r[11] ? wbs_dat_o_mux_i[11] : |
wb_slave_sel_r[12] ? wbs_dat_o_mux_i[12] : |
wb_slave_sel_r[13] ? wbs_dat_o_mux_i[13] : |
wb_slave_sel_r[14] ? wbs_dat_o_mux_i[14] : |
wb_slave_sel_r[15] ? wbs_dat_o_mux_i[15] : |
wb_slave_sel_r[16] ? wbs_dat_o_mux_i[16] : |
*/ |
wbs_dat_o_mux_i[0]; |
|
// Master out acks, or together |
assign wbm_ack_i = wbs_ack_o_mux_i[0] | |
wbs_ack_o_mux_i[1] | |
wbs_ack_o_mux_i[2] /*| |
wbs_ack_o_mux_i[3] | |
wbs_ack_o_mux_i[4] | |
wbs_ack_o_mux_i[5] | |
wbs_ack_o_mux_i[6] | |
wbs_ack_o_mux_i[7] | |
wbs_ack_o_mux_i[8] | |
wbs_ack_o_mux_i[9] | |
wbs_ack_o_mux_i[10] | |
wbs_ack_o_mux_i[11] | |
wbs_ack_o_mux_i[12] | |
wbs_ack_o_mux_i[13] | |
wbs_ack_o_mux_i[14] | |
wbs_ack_o_mux_i[15] | |
wbs_ack_o_mux_i[16] */ |
; |
|
|
assign wbm_err_i = wbs_err_o_mux_i[0] | |
wbs_err_o_mux_i[1] | |
wbs_err_o_mux_i[2] |/* |
wbs_err_o_mux_i[3] | |
wbs_err_o_mux_i[4] | |
wbs_err_o_mux_i[5] | |
wbs_err_o_mux_i[6] | |
wbs_err_o_mux_i[7] | |
wbs_err_o_mux_i[8] | |
wbs_err_o_mux_i[9] | |
wbs_err_o_mux_i[10] | |
wbs_err_o_mux_i[11] | |
wbs_err_o_mux_i[12] | |
wbs_err_o_mux_i[13] | |
wbs_err_o_mux_i[14] | |
wbs_err_o_mux_i[15] | |
wbs_err_o_mux_i[16] |*/ |
watchdog_err ; |
|
|
assign wbm_rty_i = wbs_rty_o_mux_i[0] | |
wbs_rty_o_mux_i[1] | |
wbs_rty_o_mux_i[2] /*| |
wbs_rty_o_mux_i[3] | |
wbs_rty_o_mux_i[4] | |
wbs_rty_o_mux_i[5] | |
wbs_rty_o_mux_i[6] | |
wbs_rty_o_mux_i[7] | |
wbs_rty_o_mux_i[8] | |
wbs_rty_o_mux_i[9] | |
wbs_rty_o_mux_i[10] | |
wbs_rty_o_mux_i[11] | |
wbs_rty_o_mux_i[12] | |
wbs_rty_o_mux_i[13] | |
wbs_rty_o_mux_i[14] | |
wbs_rty_o_mux_i[15] | |
wbs_rty_o_mux_i[16]*/; |
|
endmodule // arbiter_dbus |
|
/s3adsp1800/rtl/verilog/arbiter/arbiter_ibus.v
0,0 → 1,337
////////////////////////////////////////////////////////////////////// |
/// //// |
/// Wishbone arbiter, burst-compatible //// |
/// //// |
/// Simple arbiter, single master, dual slave, primarily for //// |
/// processor instruction bus, providing access to one main //// |
/// memory server and one ROM //// |
/// //// |
/// Julius Baxter, julius@opencores.org //// |
/// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009, 2010 Authors and 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
`include "orpsoc-defines.v" |
// One master, 2 slaves. |
module arbiter_ibus |
( |
// instruction bus in |
// Wishbone Master interface |
wbm_adr_o, |
wbm_dat_o, |
wbm_sel_o, |
wbm_we_o, |
wbm_cyc_o, |
wbm_stb_o, |
wbm_cti_o, |
wbm_bte_o, |
|
wbm_dat_i, |
wbm_ack_i, |
wbm_err_i, |
wbm_rty_i, |
|
|
// Slave one |
// Wishbone Slave interface |
wbs0_adr_i, |
wbs0_dat_i, |
wbs0_sel_i, |
wbs0_we_i, |
wbs0_cyc_i, |
wbs0_stb_i, |
wbs0_cti_i, |
wbs0_bte_i, |
|
wbs0_dat_o, |
wbs0_ack_o, |
wbs0_err_o, |
wbs0_rty_o, |
|
// Slave two |
// Wishbone Slave interface |
wbs1_adr_i, |
wbs1_dat_i, |
wbs1_sel_i, |
wbs1_we_i, |
wbs1_cyc_i, |
wbs1_stb_i, |
wbs1_cti_i, |
wbs1_bte_i, |
|
wbs1_dat_o, |
wbs1_ack_o, |
wbs1_err_o, |
wbs1_rty_o, |
|
wb_clk, |
wb_rst |
); |
|
|
parameter wb_dat_width = 32; |
parameter wb_adr_width = 32; |
|
parameter wb_addr_match_width = 8; |
|
parameter slave0_adr = 8'hf0; // FLASH ROM |
parameter slave1_adr = 8'h00; // Main memory (SDRAM/FPGA SRAM) |
|
`define WB_ARB_ADDR_MATCH_SEL wb_adr_width-1:wb_adr_width-wb_addr_match_width |
|
input wb_clk; |
input wb_rst; |
|
|
// WB Master |
input [wb_adr_width-1:0] wbm_adr_o; |
input [wb_dat_width-1:0] wbm_dat_o; |
input [3:0] wbm_sel_o; |
input wbm_we_o; |
input wbm_cyc_o; |
input wbm_stb_o; |
input [2:0] wbm_cti_o; |
input [1:0] wbm_bte_o; |
output [wb_dat_width-1:0] wbm_dat_i; |
output wbm_ack_i; |
output wbm_err_i; |
output wbm_rty_i; |
|
// WB Slave 0 |
output [wb_adr_width-1:0] wbs0_adr_i; |
output [wb_dat_width-1:0] wbs0_dat_i; |
output [3:0] wbs0_sel_i; |
output wbs0_we_i; |
output wbs0_cyc_i; |
output wbs0_stb_i; |
output [2:0] wbs0_cti_i; |
output [1:0] wbs0_bte_i; |
input [wb_dat_width-1:0] wbs0_dat_o; |
input wbs0_ack_o; |
input wbs0_err_o; |
input wbs0_rty_o; |
|
// WB Slave 1 |
output [wb_adr_width-1:0] wbs1_adr_i; |
output [wb_dat_width-1:0] wbs1_dat_i; |
output [3:0] wbs1_sel_i; |
output wbs1_we_i; |
output wbs1_cyc_i; |
output wbs1_stb_i; |
output [2:0] wbs1_cti_i; |
output [1:0] wbs1_bte_i; |
input [wb_dat_width-1:0] wbs1_dat_o; |
input wbs1_ack_o; |
input wbs1_err_o; |
input wbs1_rty_o; |
|
wire [1:0] slave_sel; // One bit per slave |
|
reg watchdog_err; |
|
`ifdef ARBITER_IBUS_WATCHDOG |
reg [`ARBITER_IBUS_WATCHDOG_TIMER_WIDTH:0] watchdog_timer; |
reg wbm_stb_r; // Register strobe |
wire wbm_stb_edge; // Detect its edge |
reg wbm_stb_edge_r, wbm_ack_i_r; // Reg these, better timing |
|
always @(posedge wb_clk) |
wbm_stb_r <= wbm_stb_o; |
|
assign wbm_stb_edge = (wbm_stb_o & !wbm_stb_r); |
|
always @(posedge wb_clk) |
wbm_stb_edge_r <= wbm_stb_edge; |
|
always @(posedge wb_clk) |
wbm_ack_i_r <= wbm_ack_i; |
|
|
// Counter logic |
always @(posedge wb_clk) |
if (wb_rst) watchdog_timer <= 0; |
else if (wbm_ack_i_r) // When we see an ack, turn off timer |
watchdog_timer <= 0; |
else if (wbm_stb_edge_r) // New access means start timer again |
watchdog_timer <= 1; |
else if (|watchdog_timer) // Continue counting if counter > 0 |
watchdog_timer <= watchdog_timer + 1; |
|
always @(posedge wb_clk) |
watchdog_err <= (&watchdog_timer); |
|
`else // !`ifdef ARBITER_IBUS_WATCHDOG |
|
always @(posedge wb_clk) |
watchdog_err <= 0; |
|
`endif // !`ifdef ARBITER_IBUS_WATCHDOG |
|
|
|
`ifdef ARBITER_IBUS_REGISTERING |
|
// Master input registers |
reg [wb_adr_width-1:0] wbm_adr_o_r; |
reg [wb_dat_width-1:0] wbm_dat_o_r; |
reg [3:0] wbm_sel_o_r; |
reg wbm_we_o_r; |
reg wbm_cyc_o_r; |
reg wbm_stb_o_r; |
reg [2:0] wbm_cti_o_r; |
reg [1:0] wbm_bte_o_r; |
// Slave output registers |
reg [wb_dat_width-1:0] wbs0_dat_o_r; |
reg wbs0_ack_o_r; |
reg wbs0_err_o_r; |
reg wbs0_rty_o_r; |
reg [wb_dat_width-1:0] wbs1_dat_o_r; |
reg wbs1_ack_o_r; |
reg wbs1_err_o_r; |
reg wbs1_rty_o_r; |
|
wire wbm_ack_i_pre_reg; |
|
|
|
// Register master input signals |
always @(posedge wb_clk) |
begin |
wbm_adr_o_r <= wbm_adr_o; |
wbm_dat_o_r <= wbm_dat_o; |
wbm_sel_o_r <= wbm_sel_o; |
wbm_we_o_r <= wbm_we_o; |
wbm_cyc_o_r <= wbm_cyc_o; |
wbm_stb_o_r <= wbm_stb_o & !wbm_ack_i_pre_reg & !wbm_ack_i;//classic |
wbm_cti_o_r <= wbm_cti_o; |
wbm_bte_o_r <= wbm_bte_o; |
|
// Slave signals |
wbs0_dat_o_r <= wbs0_dat_o; |
wbs0_ack_o_r <= wbs0_ack_o; |
wbs0_err_o_r <= wbs0_err_o; |
wbs0_rty_o_r <= wbs0_rty_o; |
wbs1_dat_o_r <= wbs1_dat_o; |
wbs1_ack_o_r <= wbs1_ack_o; |
wbs1_err_o_r <= wbs1_err_o; |
wbs1_rty_o_r <= wbs1_rty_o; |
|
end // always @ (posedge wb_clk) |
|
// Slave select |
assign slave_sel[0] = wbm_adr_o_r[`WB_ARB_ADDR_MATCH_SEL] == |
slave0_adr; |
|
assign slave_sel[1] = wbm_adr_o_r[`WB_ARB_ADDR_MATCH_SEL] == |
slave1_adr; |
|
// Slave out assigns |
assign wbs0_adr_i = wbm_adr_o_r; |
assign wbs0_dat_i = wbm_dat_o_r; |
assign wbs0_we_i = wbm_dat_o_r; |
assign wbs0_sel_i = wbm_sel_o_r; |
assign wbs0_cti_i = wbm_cti_o_r; |
assign wbs0_bte_i = wbm_bte_o_r; |
assign wbs0_cyc_i = wbm_cyc_o_r & slave_sel[0]; |
assign wbs0_stb_i = wbm_stb_o_r & slave_sel[0]; |
|
assign wbs1_adr_i = wbm_adr_o_r; |
assign wbs1_dat_i = wbm_dat_o_r; |
assign wbs1_we_i = wbm_dat_o_r; |
assign wbs1_sel_i = wbm_sel_o_r; |
assign wbs1_cti_i = wbm_cti_o_r; |
assign wbs1_bte_i = wbm_bte_o_r; |
assign wbs1_cyc_i = wbm_cyc_o_r & slave_sel[1]; |
assign wbs1_stb_i = wbm_stb_o_r & slave_sel[1]; |
|
// Master out assigns |
// Don't care about none selected... |
assign wbm_dat_i = slave_sel[1] ? wbs1_dat_o_r : |
wbs0_dat_o_r ; |
|
assign wbm_ack_i = (slave_sel[0] & wbs0_ack_o_r) | |
(slave_sel[1] & wbs1_ack_o_r) |
; |
|
assign wbm_err_i = (slave_sel[0] & wbs0_err_o_r) | |
(slave_sel[1] & wbs1_err_o_r) | |
watchdog_err; |
|
assign wbm_rty_i = (slave_sel[0] & wbs0_rty_o_r) | |
(slave_sel[1] & wbs1_rty_o_r); |
|
// Non-registered ack |
assign wbm_ack_i_pre_reg = (slave_sel[0] & wbs0_ack_o) | |
(slave_sel[1] & wbs1_ack_o); |
|
`else // !`ifdef ARBITER_IBUS_REGISTERING |
|
// Slave select |
assign slave_sel[0] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == |
slave0_adr; |
|
assign slave_sel[1] = wbm_adr_o[`WB_ARB_ADDR_MATCH_SEL] == |
slave1_adr; |
|
// Slave out assigns |
assign wbs0_adr_i = wbm_adr_o; |
assign wbs0_dat_i = wbm_dat_o; |
assign wbs0_we_i = wbm_we_o; |
assign wbs0_sel_i = wbm_sel_o; |
assign wbs0_cti_i = wbm_cti_o; |
assign wbs0_bte_i = wbm_bte_o; |
assign wbs0_cyc_i = wbm_cyc_o & slave_sel[0]; |
assign wbs0_stb_i = wbm_stb_o & slave_sel[0]; |
|
assign wbs1_adr_i = wbm_adr_o; |
assign wbs1_dat_i = wbm_dat_o; |
assign wbs1_we_i = wbm_we_o; |
assign wbs1_sel_i = wbm_sel_o; |
assign wbs1_cti_i = wbm_cti_o; |
assign wbs1_bte_i = wbm_bte_o; |
assign wbs1_cyc_i = wbm_cyc_o & slave_sel[1]; |
assign wbs1_stb_i = wbm_stb_o & slave_sel[1]; |
|
// Master out assigns |
// Don't care about none selected... |
assign wbm_dat_i = slave_sel[1] ? wbs1_dat_o : |
wbs0_dat_o ; |
|
assign wbm_ack_i = (slave_sel[0] & wbs0_ack_o) | |
(slave_sel[1] & wbs1_ack_o); |
|
|
assign wbm_err_i = (slave_sel[0] & wbs0_err_o) | |
(slave_sel[1] & wbs1_err_o) | |
watchdog_err; |
|
assign wbm_rty_i = (slave_sel[0] & wbs0_rty_o) | |
(slave_sel[1] & wbs1_rty_o); |
|
|
`endif |
endmodule // arbiter_ibus |
|
/s3adsp1800/rtl/verilog/gpio/gpio.v
0,0 → 1,159
/* |
* |
* Simple 24-bit wide GPIO module |
* |
* Can be made wider as needed, but must be done manually. |
* |
* First lot of bytes are the GPIO I/O regs |
* Second lot are the direction registers |
* |
* Set direction bit to '1' to output corresponding data bit. |
* |
* Register mapping: |
* |
* For 8 GPIOs we would have |
* adr 0: gpio data 7:0 |
* adr 1: gpio data 15:8 |
* adr 2: gpio data 23:16 |
* adr 3: gpio dir 7:0 |
* adr 4: gpio dir 15:8 |
* adr 5: gpio dir 23:16 |
* |
* Backend pinout file needs to be updated for any GPIO width changes. |
* |
*/ |
|
module gpio( |
wb_clk, |
wb_rst, |
|
wb_adr_i, |
wb_dat_i, |
wb_we_i, |
wb_cyc_i, |
wb_stb_i, |
wb_cti_i, |
wb_bte_i, |
|
wb_ack_o, |
wb_dat_o, |
wb_err_o, |
wb_rty_o, |
|
gpio_io); |
|
|
parameter gpio_io_width = 24; |
|
parameter gpio_dir_reset_val = 0; |
parameter gpio_o_reset_val = 0; |
|
|
parameter wb_dat_width = 8; |
parameter wb_adr_width = 3; // 8 bytes addressable |
|
input wb_clk; |
input wb_rst; |
|
input [wb_adr_width-1:0] wb_adr_i; |
input [wb_dat_width-1:0] wb_dat_i; |
input wb_we_i; |
input wb_cyc_i; |
input wb_stb_i; |
input [2:0] wb_cti_i; |
input [1:0] wb_bte_i; |
output reg [wb_dat_width-1:0] wb_dat_o; // constantly sampling gpio in bus |
output reg wb_ack_o; |
output wb_err_o; |
output wb_rty_o; |
|
inout [gpio_io_width-1:0] gpio_io; |
|
// Internal registers |
reg [gpio_io_width-1:0] gpio_dir; |
|
reg [gpio_io_width-1:0] gpio_o; |
|
wire [gpio_io_width-1:0] gpio_i; |
|
// Tristate logic for IO |
genvar i; |
generate |
for (i=0;i<gpio_io_width;i=i+1) begin: gpio_tris |
assign gpio_io[i] = (gpio_dir[i]) ? gpio_o[i] : 1'bz; |
assign gpio_i[i] = (gpio_dir[i]) ? gpio_o[i] : gpio_io[i]; |
end |
endgenerate |
|
// GPIO data out register |
always @(posedge wb_clk) |
if (wb_rst) |
gpio_o <= 0; // All set to in at reset |
else if (wb_stb_i & wb_we_i) |
begin |
if (wb_adr_i == 0) |
gpio_o[7:0] <= wb_dat_i; |
if (wb_adr_i == 1) |
gpio_o[15:8] <= wb_dat_i; |
if (wb_adr_i == 2) |
gpio_o[23:16] <= wb_dat_i; |
/* Add appropriate address detection here for wider GPIO */ |
end |
|
|
// GPIO dir register |
always @(posedge wb_clk) |
if (wb_rst) |
gpio_dir <= 0; // All set to in at reset |
else if (wb_stb_i & wb_we_i) |
begin |
if (wb_adr_i == ((gpio_io_width/8))) |
gpio_dir[7:0] <= wb_dat_i; |
if (wb_adr_i == ((gpio_io_width/8)+1)) |
gpio_dir[15:8] <= wb_dat_i; |
if (wb_adr_i == ((gpio_io_width/8)+2)) |
//gpio_dir[23:16] <= wb_dat_i; |
gpio_dir[21:16] <= wb_dat_i[5:0]; |
|
/* Add appropriate address detection here for wider GPIO */ |
|
end |
|
// Register the gpio in signal |
always @(posedge wb_clk) |
begin |
// Data regs |
if (wb_adr_i == 0) |
wb_dat_o[7:0] <= gpio_i[7:0]; |
if (wb_adr_i == 1) |
wb_dat_o[7:0] <= gpio_i[15:8]; |
if (wb_adr_i == 2) |
wb_dat_o[7:0] <= gpio_i[23:16]; |
/* Add appropriate address detection here for wider GPIO */ |
// Direction regs |
if (wb_adr_i == ((gpio_io_width/8))) |
wb_dat_o[7:0] <= gpio_dir[7:0]; |
if (wb_adr_i == ((gpio_io_width/8)+1)) |
wb_dat_o[7:0] <= gpio_dir[15:8]; |
if (wb_adr_i == ((gpio_io_width/8)+2)) |
wb_dat_o[7:0] <= gpio_dir[23:16]; |
|
/* Add appropriate address detection here for wider GPIO */ |
|
end |
|
|
// Ack generation |
always @(posedge wb_clk) |
if (wb_rst) |
wb_ack_o <= 0; |
else if (wb_ack_o) |
wb_ack_o <= 0; |
else if (wb_stb_i & !wb_ack_o) |
wb_ack_o <= 1; |
|
assign wb_err_o = 0; |
assign wb_rty_o = 0; |
|
|
endmodule // gpio |
/s3adsp1800/rtl/verilog/gpio/README
0,0 → 1,7
GPIO RTL |
|
This is a simple GPIO implementation. It is variable width, however widths of |
multiples of 8 are advised. The first width/8 bytes control are for |
reading/writing to the GPIO registers, the second set of width/8 bytes control |
the direction. |
|
/s3adsp1800/Makefile.inc
0,0 → 1,79
# Makefile fragment with some variables global to this board board |
# Expects BOARD_ROOT to be set |
|
FPGA_VENDOR=xilinx |
BOARD_NAME=s3adsp1800 |
BOARD=$(FPGA_VENDOR)/$(BOARD_NAME) |
DESIGN_NAME=orpsoc |
|
# Doc: |
# http://www.xilinx.com/support/documentation/boards_and_kits/ug454_sp3a_dsp_start_ug.pdf |
|
# Path down to root of project |
PROJECT_ROOT=$(BOARD_ROOT)/../../.. |
|
SYNTHESIS_TOOL=xst |
|
export BOARD |
|
include $(PROJECT_ROOT)/scripts/make/Makefile-misc.inc |
include $(PROJECT_ROOT)/scripts/make/Makefile-board-paths.inc |
include $(PROJECT_ROOT)/scripts/make/Makefile-board-tops.inc |
include $(PROJECT_ROOT)/scripts/make/Makefile-board-definesparse.inc |
|
# Check that the XILINX_PATH variable is set |
ifeq ($(XILINX_PATH),) |
$(error XILINX_PATH environment variable not set. Set it and rerun) |
endif |
|
#XILINX_SETTINGS_SCRIPT ?=/opt/xilinx/13.1/ISE_DS/settings32.sh |
# ISE 13.1 ISE_DS version |
XILINX_SETTINGS_SCRIPT ?=$(XILINX_PATH)/ISE_DS/settings32.sh |
XILINX_SETTINGS_SCRIPT_EXISTS=$(shell if [ -e $(XILINX_SETTINGS_SCRIPT) ]; then echo 1; else echo 0; fi) |
ifeq ($(XILINX_SETTINGS_SCRIPT_EXISTS),0) |
$(error XILINX_SETTINGS_SCRIPT variable not set correctly. Cannot find $(XILINX_SETTINGS_SCRIPT)) |
endif |
|
# Backend directories |
# This one is the board build's backend dir. |
BOARD_BACKEND_DIR=$(BOARD_ROOT)/backend |
BOARD_BACKEND_VERILOG_DIR=$(BOARD_BACKEND_DIR)/rtl/verilog |
BOARD_BACKEND_BIN_DIR=$(BOARD_BACKEND_DIR)/bin |
# Technology backend (vendor-specific) |
TECHNOLOGY_BACKEND_DIR=$(BOARD_ROOT)/../backend |
# This path is for the technology library |
TECHNOLOGY_LIBRARY_VERILOG_DIR=$(XILINX_PATH)/ISE/verilog |
|
# Bootrom setup |
# BootROM code, which generates a verilog array select values |
BOOTROM_FILE=bootrom.v |
BOOTROM_SW_DIR=$(BOARD_SW_DIR)/bootrom |
BOOTROM_SRC=$(shell ls $(BOOTROM_SW_DIR)/* | grep -v $(BOOTROM_FILE)) |
BOOTROM_VERILOG=$(BOOTROM_SW_DIR)/$(BOOTROM_FILE) |
|
bootrom: $(BOOTROM_VERILOG) |
|
$(BOOTROM_VERILOG): $(BOOTROM_SRC) |
$(Q)echo; echo "\t### Generating bootup ROM ###"; echo |
$(Q)$(MAKE) -C $(BOOTROM_SW_DIR) $(BOOTROM_FILE) |
|
clean-bootrom: |
$(Q)echo; echo "\t### Cleaning bootup ROM ###"; echo |
$(Q)$(MAKE) -C $(BOOTROM_SW_DIR) clean |
|
include $(PROJECT_ROOT)/scripts/make/Makefile-board-rtlmodules.inc |
|
# "Backend" source file stuff (PLL, RAM macro models.) |
BOARD_BACKEND_VERILOG_SRC=$(shell ls $(BOARD_BACKEND_VERILOG_DIR)/*.v ) |
|
# Backend tool path |
|
# BACKEND_TECHNOLOGY_VERILOG_SRC should be set if we need to compile specific |
# libraries, as in the Actel and Altera case, and left empty for Xilinx who |
# allow us to simply pass the path with the -y option because they have each |
# bit of the tech library in individual files, and in which case this variable |
# should be left unset. |
|
# Keep this variable empty |
BACKEND_TECHNOLOGY_VERILOG_SRC= |
|
/s3adsp1800/backend/par/run/Makefile
0,0 → 1,2
include ../bin/Makefile |
|
/s3adsp1800/backend/par/bin/s3adsp1800.ucf
0,0 → 1,1385
############################################################################ |
## _____ |
## / \ |
## /____ \____ |
## / \===\ \==/ |
##/___\===\___\/ AVNET Design Resource Center |
## \======/ www.em.avnet.com/drc |
## \====/ www.em.avnet.com/spartan3a-dsp |
##---------------------------------------------------------------- |
## |
## Disclaimer: |
## Avnet, Inc. makes no warranty for the use of this code or design. |
## This code is provided "As Is". Avnet, Inc assumes no responsibility for |
## any errors, which may appear in this code, nor does it make a commitment |
## to update the information contained herein. Avnet, Inc specifically |
## disclaims any implied warranties of fitness for a particular purpose. |
## Copyright(c) 2007 Avnet, Inc. |
## All rights reserved. |
## |
############################################################################ |
|
## Spartan-3A Specific constraints |
CONFIG VCCAUX=3.3; |
|
#### System level constraints |
|
# Net sys_clk_i LOC = "AE13" | IOSTANDARD = LVCMOS33 ; # socket clock |
Net sys_clk_i LOC = "F13" | IOSTANDARD = LVCMOS33 ; # 125 MHz clock |
# Net sys_clk_i LOC = "K14" | IOSTANDARD = LVCMOS33 ; # SMA clock |
|
Net rst_n_pad_i LOC="Y16" | IOSTANDARD = LVTTL; |
Net rst_n_pad_i TIG; |
#NET "mb_opb_OPB_Rst" TIG; |
|
#### Timing constraints |
|
Net sys_clk_i TNM_NET = sys_clk_i; |
TIMESPEC TS_sys_clk_i = PERIOD sys_clk_i 8000 ps; # 125MHz |
|
# Can't see any FB nets in DDR2 design from MIG - Julius |
#Net fpga_0_DDR_CLK_FB TNM_NET = fpga_0_DDR_CLK_FB; |
#TIMESPEC TS_fpga_0_DDR_CLK_FB = PERIOD fpga_0_DDR_CLK_FB 8000 ps; # 125MHz |
|
# Not using this clock - Julius |
#Net CLK_25_175MHZ TNM_NET = CLK_25_175MHZ; |
#TIMESPEC TS_CLK_25_175MHZ = PERIOD CLK_25_175MHZ 39700 ps; # 25.175MHz |
#INST "CLK_25_175MHZ_BUFGP/BUFG" LOC = "BUFGMUX_X3Y2"; |
|
#### Module RS232 constraints |
|
Net uart0_srx_pad_i LOC="N21" | IOSTANDARD = LVTTL; |
Net uart0_stx_pad_o LOC="P22" | IOSTANDARD = LVTTL | DRIVE = 4 | SLEW = SLOW; |
|
#### Module LEDs_8Bit constraints |
|
#Net fpga_0_LEDs_8Bit_GPIO_d_out* TIG; |
Net gpio0_io[*] TIG; |
Net gpio0_io<0> LOC="D25" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ; |
Net gpio0_io<1> LOC="D24" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ; |
Net gpio0_io<2> LOC="G21" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ; |
Net gpio0_io<3> LOC="H20" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ; |
Net gpio0_io<4> LOC="K22" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ; |
Net gpio0_io<5> LOC="N19" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ; |
Net gpio0_io<6> LOC="P25" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ; |
Net gpio0_io<7> LOC="P18" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ; |
|
#### Module DIP_Switches_8Bit constraints |
|
#Net fpga_0_DIP_Switches_8Bit_GPIO_in* TIG; |
|
#Net gpio0_io<8> LOC="A23" | IOSTANDARD = LVTTL; |
#Net gpio0_io<9> LOC="A5" | IOSTANDARD = LVTTL; |
#Net gpio0_io<10> LOC="B24" | IOSTANDARD = LVTTL; |
#Net gpio0_io<11> LOC="D19" | IOSTANDARD = LVTTL; |
#Net gpio0_io<12> LOC="D15" | IOSTANDARD = LVTTL; |
#Net gpio0_io<13> LOC="E9" | IOSTANDARD = LVTTL; |
#Net gpio0_io<14> LOC="G16" | IOSTANDARD = LVTTL; |
#Net gpio0_io<15> LOC="A7" | IOSTANDARD = LVTTL; |
|
#### Module Buttons_4Bit constraints |
|
#Net gpio0_io<16> LOC = "J17" | IOSTANDARD = LVTTL; |
#Net gpio0_io<17> LOC = "J15" | IOSTANDARD = LVTTL; |
#Net gpio0_io<18> LOC = "J13" | IOSTANDARD = LVTTL; |
#Net gpio0_io<19> LOC = "J10" | IOSTANDARD = LVTTL; |
|
# GPIO pads which can have I/O bufs - on J8 SysAce header |
Net gpio0_io<8> LOC = "U18" | IOSTANDARD = LVTTL; |
Net gpio0_io<9> LOC = "Y22" | IOSTANDARD = LVTTL; |
Net gpio0_io<10> LOC = "Y23" | IOSTANDARD = LVTTL; |
Net gpio0_io<11> LOC = "U21" | IOSTANDARD = LVTTL; |
Net gpio0_io<12> LOC = "T20" | IOSTANDARD = LVTTL; |
Net gpio0_io<13> LOC = "Y24" | IOSTANDARD = LVTTL; |
Net gpio0_io<14> LOC = "Y25" | IOSTANDARD = LVTTL; |
Net gpio0_io<15> LOC = "T18" | IOSTANDARD = LVTTL; |
Net gpio0_io<16> LOC = "T17" | IOSTANDARD = LVTTL; |
Net gpio0_io<17> LOC = "W23" | IOSTANDARD = LVTTL; |
Net gpio0_io<18> LOC = "V25" | IOSTANDARD = LVTTL; |
Net gpio0_io<19> LOC = "V22" | IOSTANDARD = LVTTL; |
Net gpio0_io<20> LOC = "V24" | IOSTANDARD = LVTTL; |
Net gpio0_io<21> LOC = "V23" | IOSTANDARD = LVTTL; |
Net gpio0_io<22> LOC = "AC26" | IOSTANDARD = LVTTL; |
Net gpio0_io<23> LOC = "AB26" | IOSTANDARD = LVTTL; |
|
|
#### Module DDR2_SDRAM_32Mx32 constraints |
|
################################################################################################## |
## Clock constraints |
################################################################################################## |
#NET "*/infrastructure_top0/sys_clk_ibuf" TNM_NET = "SYS_CLK"; |
#TIMESPEC "TS_SYS_CLK" = PERIOD "SYS_CLK" 7.519000 ns HIGH 50 %; |
################################################################################################## |
|
################################################################################################## |
## These paths are constrained to get rid of unconstrained paths. |
################################################################################################## |
NET "*/infrastructure_top0/clk_dcm0/clk0dcm" TNM_NET = "clk0"; |
#NET "xilinx_s3adsp_ddr2/xilinx_s3adsp_ddr2_if/s3adsp_ddr2/top_00/data_path0/dqs_delayed_col*" TNM_NET = "dqs_clk"; |
NET "*/top_00/data_path0/dqs_delayed_col*" TNM_NET = "dqs_clk"; |
TIMESPEC "TS_CLK" = FROM "clk0" TO "dqs_clk" 18 ns DATAPATHONLY; |
|
NET "*/infrastructure_top0/clk_dcm0/clk90dcm" TNM_NET = "clk90"; |
TIMESPEC "TS_CLK90" = FROM "dqs_clk" TO "clk90" 18 ns DATAPATHONLY; |
TIMESPEC "TS_DQSCLK" = FROM "clk90" TO "dqs_clk" 18 ns DATAPATHONLY; |
|
#NET "*/top_00/data_path0/data_read_controller0/gen_wr_en*fifo*_wr_en_inst/clk" TNM_NET = "fifo_we_clk"; |
NET "*/top_00/data_path0/dqs_delayed_col0[*]" TNM_NET = "fifo_we_clk"; |
|
TIMESPEC "TS_WE_CLK" = FROM "dqs_clk" TO "fifo_we_clk" 5 ns DATAPATHONLY; |
|
#NET "*/top_00/data_path0/data_read_controller0/gen_wr_addr*fifo*_wr_addr_inst/clk" TNM_NET = "fifo_waddr_clk"; |
|
NET "*/top_00/data_path0/dqs_delayed_col0[*]" TNM_NET = "fifo_waddr_clk"; |
TIMESPEC "TS_WADDR_CLK" = FROM "dqs_clk" TO "fifo_waddr_clk" 5 ns DATAPATHONLY; |
|
NET "*/top_00/data_path0/dqs_delayed_col1[*]" TNM_NET = "fifo_waddr_clk1"; |
TIMESPEC "TS_WADDR_CLK" = FROM "dqs_clk" TO "fifo_waddr_clk1" 5 ns DATAPATHONLY; |
|
############################################################################################################# |
## Calibration Circuit Constraints |
############################################################################################################# |
## Placement constraints for LUTS in tap delay ckt |
############################################################################################################# |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l0" RLOC=X0Y6; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l0" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l1" RLOC=X0Y6; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l1" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l2" RLOC=X0Y7; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l2" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l3" RLOC=X0Y7; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l3" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l4" RLOC=X1Y6; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l4" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l5" RLOC=X1Y6; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l5" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l6" RLOC=X1Y7; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l6" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l7" RLOC=X1Y7; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l7" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l8" RLOC=X0Y4; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l8" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l9" RLOC=X0Y4; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l9" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l10" RLOC=X0Y5; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l10" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l11" RLOC=X0Y5; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l11" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l12" RLOC=X1Y4; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l12" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l13" RLOC=X1Y4; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l13" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l14" RLOC=X1Y5; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l14" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l15" RLOC=X1Y5; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l15" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l16" RLOC=X0Y2; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l16" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l17" RLOC=X0Y2; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l17" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l18" RLOC=X0Y3; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l18" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l19" RLOC=X0Y3; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l19" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l20" RLOC=X1Y2; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l20" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l21" RLOC=X1Y2; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l21" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l22" RLOC=X1Y3; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l22" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l23" RLOC=X1Y3; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l23" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l24" RLOC=X0Y0; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l24" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l25" RLOC=X0Y0; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l25" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l26" RLOC=X0Y1; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l26" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l27" RLOC=X0Y1; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l27" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l28" RLOC=X1Y0; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l28" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l29" RLOC=X1Y0; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l29" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l30" RLOC=X1Y1; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l30" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/l31" RLOC=X1Y1; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l31" U_SET = delay_calibration_chain; |
|
##################################################################################################### |
# Placement constraints for first stage flops in tap delay ckt |
##################################################################################################### |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[0].r" RLOC=X0Y6; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[0].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[1].r" RLOC=X0Y6; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[1].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[2].r" RLOC=X0Y7; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[2].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[3].r" RLOC=X0Y7; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[3].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[4].r" RLOC=X1Y6; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[4].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[5].r" RLOC=X1Y6; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[5].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[6].r" RLOC=X1Y7; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[6].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[7].r" RLOC=X1Y7; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[7].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[8].r" RLOC=X0Y4; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[8].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[9].r" RLOC=X0Y4; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[9].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[10].r" RLOC=X0Y5; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[10].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[11].r" RLOC=X0Y5; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[11].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[12].r" RLOC=X1Y4; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[12].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[13].r" RLOC=X1Y4; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[13].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[14].r" RLOC=X1Y5; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[14].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[15].r" RLOC=X1Y5; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[15].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[16].r" RLOC=X0Y2; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[16].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[17].r" RLOC=X0Y2; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[17].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[18].r" RLOC=X0Y3; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[18].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[19].r" RLOC=X0Y3; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[19].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[20].r" RLOC=X1Y2; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[20].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[21].r" RLOC=X1Y2; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[21].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[22].r" RLOC=X1Y3; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[22].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[23].r" RLOC=X1Y3; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[23].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[24].r" RLOC=X0Y0; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[24].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[25].r" RLOC=X0Y0; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[25].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[26].r" RLOC=X0Y1; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[26].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[27].r" RLOC=X0Y1; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[27].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[28].r" RLOC=X1Y0; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[28].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[29].r" RLOC=X1Y0; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[29].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[30].r" RLOC=X1Y1; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[30].r" U_SET = delay_calibration_chain; |
|
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[31].r" RLOC=X1Y1; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/gen_tap1[31].r" U_SET = delay_calibration_chain; |
|
######################################################################################################### |
## BEL constraints for LUTS in tap delay ckt |
######################################################################################################### |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l0" BEL= G; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l1" BEL= F; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l2" BEL= G; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l3" BEL= F; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l4" BEL= G; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l5" BEL= F; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l6" BEL= G; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l7" BEL= F; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l8" BEL= G; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l9" BEL= F; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l10" BEL= G; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l11" BEL= F; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l12" BEL= G; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l13" BEL= F; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l14" BEL= G; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l15" BEL= F; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l16" BEL= G; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l17" BEL= F; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l18" BEL= G; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l19" BEL= F; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l20" BEL= G; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l21" BEL= F; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l22" BEL= G; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l23" BEL= F; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l24" BEL= G; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l25" BEL= F; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l26" BEL= G; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l27" BEL= F; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l28" BEL= G; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l29" BEL= F; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l30" BEL= G; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l31" BEL= F; |
|
|
|
################################################################################################## |
## RLOC Origin constraint for LUT delay calibration chain. |
################################################################################################## |
INST "*/infrastructure_top0/cal_top0/tap_dly0/l0" RLOC_ORIGIN = X42Y154; |
|
################################################################################################## |
## Area Group Constraint For tap_dly and cal_ctl module. |
################################################################################################## |
INST "*/infrastructure_top0/cal_top0/cal_ctl0/*" AREA_GROUP = cal_ctl; |
INST "*/infrastructure_top0/cal_top0/tap_dly0/*" AREA_GROUP = cal_ctl; |
AREA_GROUP "cal_ctl" RANGE = SLICE_X42Y154:SLICE_X53Y167; |
AREA_GROUP "cal_ctl" GROUP = CLOSED; |
|
################################################################################################## |
|
#***********************************************************************************************************# |
# CONTROLLER 0 |
#***********************************************************************************************************# |
|
################################################################################################## |
# I/O STANDARDS |
################################################################################################## |
NET "ddr2_dq[*]" IOSTANDARD = SSTL18_II; |
NET "ddr2_a[*]" IOSTANDARD = SSTL18_II; |
NET "ddr2_ba[*]" IOSTANDARD = SSTL18_II; |
NET "ddr2_cke" IOSTANDARD = SSTL18_II; |
NET "ddr2_cs_n" IOSTANDARD = SSTL18_II; |
NET "ddr2_ras_n" IOSTANDARD = SSTL18_II; |
NET "ddr2_cas_n" IOSTANDARD = SSTL18_II; |
NET "ddr2_we_n" IOSTANDARD = SSTL18_II; |
NET "ddr2_odt" IOSTANDARD = SSTL18_II; |
NET "ddr2_dm[*]" IOSTANDARD = SSTL18_II; |
NET "ddr2_rst_dqs_div_in" IOSTANDARD = SSTL18_II; |
NET "ddr2_rst_dqs_div_out" IOSTANDARD = SSTL18_II; |
NET "ddr2_dqs[*]" IOSTANDARD = DIFF_SSTL18_II; |
NET "ddr2_dqs_n[*]" IOSTANDARD = DIFF_SSTL18_II; |
NET "ddr2_ck[*]" IOSTANDARD = DIFF_SSTL18_II; |
NET "ddr2_ck_n[*]" IOSTANDARD = DIFF_SSTL18_II; |
|
|
################################################################################################## |
# Pin Location Constraints for Clock,Masks, Address, and Controls |
################################################################################################## |
# New UCF (from MIG, updated with correct pins from schematic) |
|
NET "ddr2_ck[0]" LOC = "N1" ; #bank 3 |
NET "ddr2_ck_n[0]" LOC = "N2" ; #bank 3 |
NET "ddr2_ck[1]" LOC = "N5" ; #bank 3 |
NET "ddr2_ck_n[1]" LOC = "N4" ; #bank 3 |
|
NET "ddr2_dm[0]" LOC = "V2" ; #bank 3 |
NET "ddr2_dm[1]" LOC = "V1" ; #bank 3 |
NET "ddr2_dm[2]" LOC = "R2" ; #bank 3 |
NET "ddr2_dm[3]" LOC = "M6" ; #bank 3 |
|
NET "ddr2_a[12]" LOC = "M4" ; #bank 3 |
NET "ddr2_a[11]" LOC = "M3" ; #bank 3 |
NET "ddr2_a[10]" LOC = "M8" ; #bank 3 |
NET "ddr2_a[9]" LOC = "M7" ; #bank 3 |
NET "ddr2_a[8]" LOC = "L4" ; #bank 3 |
NET "ddr2_a[7]" LOC = "L3" ; #bank 3 |
NET "ddr2_a[6]" LOC = "K3" ; #bank 3 |
NET "ddr2_a[5]" LOC = "K2" ; #bank 3 |
NET "ddr2_a[4]" LOC = "K5" ; #bank 3 |
NET "ddr2_a[3]" LOC = "K4" ; #bank 3 |
NET "ddr2_a[2]" LOC = "M10" ; #bank 3 |
NET "ddr2_a[1]" LOC = "M9" ; #bank 3 |
NET "ddr2_a[0]" LOC = "J5" ; #bank 3 |
|
NET "ddr2_ba[1]" LOC = "J4" ; #bank 3 |
NET "ddr2_ba[0]" LOC = "K6" ; #bank 3 |
|
NET "ddr2_cke" LOC = "L7" ; #bank 3 |
NET "ddr2_cs_n" LOC = "H2" ; #bank 3 |
NET "ddr2_ras_n" LOC = "H1" ; #bank 3 |
NET "ddr2_cas_n" LOC = "L10" ; #bank 3 |
NET "ddr2_we_n" LOC = "L9" ; #bank 3 |
NET "ddr2_odt" LOC = "G3" ; #bank 3 |
|
################################################################################################## |
## There is an issue with Xilinx ISE_DS 10.1 tool, default drive strength of LVCMOS18 for Spartan-3A |
## should set to 8MA for top/bottom banks, the tool is setting it to 12MA. |
## We are setting the drive strength to 8MA in UCF file for following signal/signals |
## as work aroud until the ISE bug is fixed |
|
################################################################################################## |
|
################################################################################################## |
## MAXDELAY constraints |
################################################################################################## |
|
################################################################################################## |
## Constraint to have the tap delay inverter connection wire length to be the same and minimum to get |
## accurate calibration of tap delays. The following constraints are independent of frequency. |
################################################################################################## |
NET "*/infrastructure_top0/cal_top0/tap_dly0/tap[7]" MAXDELAY = 400 ps; |
NET "*/infrastructure_top0/cal_top0/tap_dly0/tap[15]" MAXDELAY = 400 ps; |
NET "*/infrastructure_top0/cal_top0/tap_dly0/tap[23]" MAXDELAY = 400 ps; |
|
################################################################################################## |
## MAXDELAY constraint on inter LUT delay elements. This constraint is required to minimize the |
## wire delays between the LUTs. |
################################################################################################## |
NET "*/data_path0/data_read_controller0/gen_delay*dqs_delay_col*/delay*" MAXDELAY = 190 ps; |
NET "*/data_path0/data_read_controller0/rst_dqs_div_delayed/delay*" MAXDELAY = 200 ps; |
|
################################################################################################## |
## Constraint from the dqs PAD to input of LUT delay element. |
################################################################################################## |
NET "*/dqs_int_delay_in*" MAXDELAY = 661 ps; |
|
################################################################################################## |
## Constraint from rst_dqs_div_in PAD to input of LUT delay element. |
################################################################################################## |
NET "*/dqs_div_rst" MAXDELAY = 468 ps; |
|
################################################################################################## |
## Following are the MAXDELAY constraints on delayed rst_dqs_div net and fifo write enable signals. |
## These constraints are required since these paths are not covered by timing analysis. The requirement is total |
## delay on delayed rst_dqs_div and fifo_wr_en nets should not exceed the clock period. |
################################################################################################## |
NET "*/data_path0/data_read_controller0/rst_dqs_div" MAXDELAY = 3007 ps; |
#NET "*/data_path0/data_read0/fifo*_wr_en*" MAXDELAY = 3007 ps; |
NET "*/data_path0/fifo*_wr_en[*]" MAXDELAY = 3007 ps; |
|
################################################################################################## |
## The MAXDELAY value on fifo write address should be less than clock period. This constraint is |
## required since this path is not covered by timing analysis. |
################################################################################################## |
#NET "*/data_path0/data_read0/fifo*_wr_addr[*]" MAXDELAY = 6391 ps; |
NET "*/data_path0/fifo*_wr_addr[*]" MAXDELAY = 6391 ps; |
|
################################################################################################## |
|
################################################################################################## |
## constraints for bit ddr2_dq, 1, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[1]" LOC = "V8"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[0].strobe/fifo_bit1" LOC = SLICE_X2Y26; |
INST "*/data_path0/data_read0/gen_strobe[0].strobe_n/fifo_bit1" LOC = SLICE_X2Y27; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 0, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[0]" LOC = "U9"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[0].strobe/fifo_bit0" LOC = SLICE_X0Y26; |
INST "*/data_path0/data_read0/gen_strobe[0].strobe_n/fifo_bit0" LOC = SLICE_X0Y27; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 3, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[3]" LOC = "AC1"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[0].strobe/fifo_bit3" LOC = SLICE_X2Y28; |
INST "*/data_path0/data_read0/gen_strobe[0].strobe_n/fifo_bit3" LOC = SLICE_X2Y29; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 2, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[2]" LOC = "AB1"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[0].strobe/fifo_bit2" LOC = SLICE_X0Y28; |
INST "*/data_path0/data_read0/gen_strobe[0].strobe_n/fifo_bit2" LOC = SLICE_X0Y29; |
|
################################################################################################## |
## constraints for bit ddr2_dqs_n, 0, location in tile: 0 |
################################################################################################## |
NET "ddr2_dqs_n[0]" LOC = "V6"; #bank 3 |
|
################################################################################################## |
## constraints for bit ddr2_dqs, 0, location in tile: 0 |
################################################################################################## |
NET "ddr2_dqs[0]" LOC = "V7"; #bank 3 |
|
################################################################################################## |
## LUT location constraints for dqs_delayed_col0 |
################################################################################################## |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col0/one" LOC = SLICE_X2Y31; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col0/one" BEL = F; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col0/two" LOC = SLICE_X2Y31; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col0/two" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col0/three" LOC = SLICE_X2Y30; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col0/three" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col0/four" LOC = SLICE_X2Y30; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col0/four" BEL = F; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col0/five" LOC = SLICE_X3Y31; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col0/five" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col0/six" LOC = SLICE_X3Y30; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col0/six" BEL = G; |
|
################################################################################################## |
## LUT location constraints for dqs_delayed_col1 |
################################################################################################## |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col1/one" LOC = SLICE_X0Y31; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col1/one" BEL = F; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col1/two" LOC = SLICE_X0Y31; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col1/two" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col1/three" LOC = SLICE_X0Y30; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col1/three" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col1/four" LOC = SLICE_X0Y30; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col1/four" BEL = F; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col1/five" LOC = SLICE_X1Y31; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col1/five" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col1/six" LOC = SLICE_X1Y30; |
INST "*/data_path0/data_read_controller0/gen_delay[0].dqs_delay_col1/six" BEL = G; |
|
################################################################################################## |
## Slice location constraints for Fifo write address and write enable |
################################################################################################## |
INST "*/data_path0/data_read_controller0/gen_wr_addr[0].fifo_0_wr_addr_inst/bit0" LOC = SLICE_X1Y26; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[0].fifo_0_wr_addr_inst/bit1" LOC = SLICE_X1Y26; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[0].fifo_0_wr_addr_inst/bit2" LOC = SLICE_X1Y27; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[0].fifo_0_wr_addr_inst/bit3" LOC = SLICE_X1Y27; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[0].fifo_1_wr_addr_inst/bit0" LOC = SLICE_X3Y26; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[0].fifo_1_wr_addr_inst/bit1" LOC = SLICE_X3Y26; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[0].fifo_1_wr_addr_inst/bit2" LOC = SLICE_X3Y27; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[0].fifo_1_wr_addr_inst/bit3" LOC = SLICE_X3Y27; |
#INST "*/data_path0/data_read_controller0/gen_wr_en[0].fifo_0_wr_en_inst" LOC = SLICE_X1Y29; |
INST "*/data_path0/data_read_controller0/gen_wr_en[0].fifo_0_wr_en_inst/dout*" LOC = SLICE_X1Y29; |
#INST "*/data_path0/data_read_controller0/gen_wr_en[0].fifo_1_wr_en_inst" LOC = SLICE_X3Y29; |
INST "*data_path0/data_read_controller0/gen_wr_en[0].fifo_1_wr_en_inst/dout*" LOC = SLICE_X3Y29; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 5, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[5]" LOC = "Y6"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[0].strobe/fifo_bit5" LOC = SLICE_X2Y34; |
INST "*/data_path0/data_read0/gen_strobe[0].strobe_n/fifo_bit5" LOC = SLICE_X2Y35; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 4, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[4]" LOC = "Y5"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[0].strobe/fifo_bit4" LOC = SLICE_X0Y34; |
INST "*/data_path0/data_read0/gen_strobe[0].strobe_n/fifo_bit4" LOC = SLICE_X0Y35; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 7, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[7]" LOC = "U8"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[0].strobe/fifo_bit7" LOC = SLICE_X2Y36; |
INST "*/data_path0/data_read0/gen_strobe[0].strobe_n/fifo_bit7" LOC = SLICE_X2Y37; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 6, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[6]" LOC = "U7"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[0].strobe/fifo_bit6" LOC = SLICE_X0Y36; |
INST "*/data_path0/data_read0/gen_strobe[0].strobe_n/fifo_bit6" LOC = SLICE_X0Y37; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 9, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[9]" LOC = "AA3"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[1].strobe/fifo_bit1" LOC = SLICE_X2Y38; |
INST "*/data_path0/data_read0/gen_strobe[1].strobe_n/fifo_bit1" LOC = SLICE_X2Y39; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 8, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[8]" LOC = "AA2"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[1].strobe/fifo_bit0" LOC = SLICE_X0Y38; |
INST "*/data_path0/data_read0/gen_strobe[1].strobe_n/fifo_bit0" LOC = SLICE_X0Y39; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 11, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[11]" LOC = "Y2"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[1].strobe/fifo_bit3" LOC = SLICE_X2Y42; |
INST "*/data_path0/data_read0/gen_strobe[1].strobe_n/fifo_bit3" LOC = SLICE_X2Y43; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 10, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[10]" LOC = "Y1"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[1].strobe/fifo_bit2" LOC = SLICE_X0Y42; |
INST "*/data_path0/data_read0/gen_strobe[1].strobe_n/fifo_bit2" LOC = SLICE_X0Y43; |
|
################################################################################################## |
## constraints for bit ddr2_dqs_n, 1, location in tile: 0 |
################################################################################################## |
NET "ddr2_dqs_n[1]" LOC = "W4"; #bank 3 |
|
################################################################################################## |
## constraints for bit ddr2_dqs, 1, location in tile: 0 |
################################################################################################## |
NET "ddr2_dqs[1]" LOC = "W3"; #bank 3 |
|
################################################################################################## |
## LUT location constraints for dqs_delayed_col0 |
################################################################################################## |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col0/one" LOC = SLICE_X2Y45; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col0/one" BEL = F; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col0/two" LOC = SLICE_X2Y45; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col0/two" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col0/three" LOC = SLICE_X2Y44; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col0/three" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col0/four" LOC = SLICE_X2Y44; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col0/four" BEL = F; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col0/five" LOC = SLICE_X3Y45; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col0/five" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col0/six" LOC = SLICE_X3Y44; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col0/six" BEL = G; |
|
################################################################################################## |
## LUT location constraints for dqs_delayed_col1 |
################################################################################################## |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col1/one" LOC = SLICE_X0Y45; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col1/one" BEL = F; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col1/two" LOC = SLICE_X0Y45; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col1/two" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col1/three" LOC = SLICE_X0Y44; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col1/three" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col1/four" LOC = SLICE_X0Y44; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col1/four" BEL = F; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col1/five" LOC = SLICE_X1Y45; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col1/five" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col1/six" LOC = SLICE_X1Y44; |
INST "*/data_path0/data_read_controller0/gen_delay[1].dqs_delay_col1/six" BEL = G; |
|
################################################################################################## |
## Slice location constraints for Fifo write address and write enable |
################################################################################################## |
INST "*/data_path0/data_read_controller0/gen_wr_addr[1].fifo_0_wr_addr_inst/bit0" LOC = SLICE_X1Y40; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[1].fifo_0_wr_addr_inst/bit1" LOC = SLICE_X1Y40; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[1].fifo_0_wr_addr_inst/bit2" LOC = SLICE_X1Y41; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[1].fifo_0_wr_addr_inst/bit3" LOC = SLICE_X1Y41; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[1].fifo_1_wr_addr_inst/bit0" LOC = SLICE_X3Y40; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[1].fifo_1_wr_addr_inst/bit1" LOC = SLICE_X3Y40; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[1].fifo_1_wr_addr_inst/bit2" LOC = SLICE_X3Y41; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[1].fifo_1_wr_addr_inst/bit3" LOC = SLICE_X3Y41; |
#INST "*/data_path0/data_read_controller0/gen_wr_en[1].fifo_0_wr_en_inst" LOC = SLICE_X1Y43; |
INST "*/data_path0/data_read_controller0/gen_wr_en[1].fifo_0_wr_en_inst/dout*" LOC = SLICE_X1Y43; |
#INST "*/data_path0/data_read_controller0/gen_wr_en[1].fifo_1_wr_en_inst" LOC = SLICE_X3Y43; |
INST "*/data_path0/data_read_controller0/gen_wr_en[1].fifo_1_wr_en_inst/dout*" LOC = SLICE_X3Y43; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 13, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[13]" LOC = "U6"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[1].strobe/fifo_bit5" LOC = SLICE_X2Y46; |
INST "*/data_path0/data_read0/gen_strobe[1].strobe_n/fifo_bit5" LOC = SLICE_X2Y47; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 12, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[12]" LOC = "T7"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[1].strobe/fifo_bit4" LOC = SLICE_X0Y46; |
INST "*/data_path0/data_read0/gen_strobe[1].strobe_n/fifo_bit4" LOC = SLICE_X0Y47; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 15, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[15]" LOC = "V5"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[1].strobe/fifo_bit7" LOC = SLICE_X2Y50; |
INST "*/data_path0/data_read0/gen_strobe[1].strobe_n/fifo_bit7" LOC = SLICE_X2Y51; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 14, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[14]" LOC = "U5"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[1].strobe/fifo_bit6" LOC = SLICE_X0Y50; |
INST "*/data_path0/data_read0/gen_strobe[1].strobe_n/fifo_bit6" LOC = SLICE_X0Y51; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 16, location in tile: 0 |
################################################################################################## |
# Not correct! Schematic on board says R8 Julius |
#NET "ddr2_dq[16]" LOC = "V1"; #bank 3 |
#INST "*/data_path0/data_read0/gen_strobe[2].strobe/fifo_bit0" LOC = SLICE_X0Y54; |
#INST "*/data_path0/data_read0/gen_strobe[2].strobe_n/fifo_bit0" LOC = SLICE_X0Y55; |
|
NET "ddr2_dq[16]" LOC = "R8"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[2].strobe/fifo_bit0" LOC = SLICE_X0Y58; |
INST "*/data_path0/data_read0/gen_strobe[2].strobe_n/fifo_bit0" LOC = SLICE_X0Y59; |
|
|
################################################################################################## |
## constraints for bit ddr2_dq, 17, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[17]" LOC = "R7"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[2].strobe/fifo_bit1" LOC = SLICE_X2Y58; |
INST "*/data_path0/data_read0/gen_strobe[2].strobe_n/fifo_bit1" LOC = SLICE_X2Y59; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 18, location in tile: 0 |
################################################################################################## |
# Not correct! Schematic says U1 for this bit. - Julius |
# |
#NET "ddr2_dq[18]" LOC = "R8"; #bank 3 |
#INST "*/data_path0/data_read0/gen_strobe[2].strobe/fifo_bit2" LOC = SLICE_X0Y58; |
#INST "*/data_path0/data_read0/gen_strobe[2].strobe_n/fifo_bit2" LOC = SLICE_X0Y59; |
|
NET "ddr2_dq[18]" LOC = "U1"; #bank 3 |
|
################################################################################################## |
## constraints for bit ddr2_dq, 19, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[19]" LOC = "U2"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[2].strobe/fifo_bit3" LOC = SLICE_X2Y60; |
INST "*/data_path0/data_read0/gen_strobe[2].strobe_n/fifo_bit3" LOC = SLICE_X2Y61; |
|
################################################################################################## |
## constraints for bit ddr2_dqs_n, 2, location in tile: 0 |
################################################################################################## |
NET "ddr2_dqs_n[2]" LOC = "U4"; #bank 3 |
|
################################################################################################## |
## constraints for bit ddr2_dqs, 2, location in tile: 0 |
################################################################################################## |
NET "ddr2_dqs[2]" LOC = "T5"; #bank 3 |
|
################################################################################################## |
## LUT location constraints for dqs_delayed_col0 |
################################################################################################## |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col0/one" LOC = SLICE_X2Y67; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col0/one" BEL = F; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col0/two" LOC = SLICE_X2Y67; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col0/two" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col0/three" LOC = SLICE_X2Y66; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col0/three" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col0/four" LOC = SLICE_X2Y66; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col0/four" BEL = F; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col0/five" LOC = SLICE_X3Y67; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col0/five" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col0/six" LOC = SLICE_X3Y66; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col0/six" BEL = G; |
|
################################################################################################## |
## LUT location constraints for dqs_delayed_col1 |
################################################################################################## |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col1/one" LOC = SLICE_X0Y67; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col1/one" BEL = F; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col1/two" LOC = SLICE_X0Y67; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col1/two" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col1/three" LOC = SLICE_X0Y66; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col1/three" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col1/four" LOC = SLICE_X0Y66; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col1/four" BEL = F; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col1/five" LOC = SLICE_X1Y67; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col1/five" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col1/six" LOC = SLICE_X1Y66; |
INST "*/data_path0/data_read_controller0/gen_delay[2].dqs_delay_col1/six" BEL = G; |
|
################################################################################################## |
## Slice location constraints for Fifo write address and write enable |
################################################################################################## |
INST "*/data_path0/data_read_controller0/gen_wr_addr[2].fifo_0_wr_addr_inst/bit0" LOC = SLICE_X1Y62; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[2].fifo_0_wr_addr_inst/bit1" LOC = SLICE_X1Y62; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[2].fifo_0_wr_addr_inst/bit2" LOC = SLICE_X1Y63; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[2].fifo_0_wr_addr_inst/bit3" LOC = SLICE_X1Y63; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[2].fifo_1_wr_addr_inst/bit0" LOC = SLICE_X3Y62; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[2].fifo_1_wr_addr_inst/bit1" LOC = SLICE_X3Y62; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[2].fifo_1_wr_addr_inst/bit2" LOC = SLICE_X3Y63; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[2].fifo_1_wr_addr_inst/bit3" LOC = SLICE_X3Y63; |
#INST "*/data_path0/data_read_controller0/gen_wr_en[2].fifo_0_wr_en_inst" LOC = SLICE_X1Y65; |
INST "*/data_path0/data_read_controller0/gen_wr_en[2].fifo_0_wr_en_inst/dout*" LOC = SLICE_X1Y65; |
#INST "*/data_path0/data_read_controller0/gen_wr_en[2].fifo_1_wr_en_inst" LOC = SLICE_X3Y65; |
INST "*/data_path0/data_read_controller0/gen_wr_en[2].fifo_1_wr_en_inst/dout*" LOC = SLICE_X3Y65; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 21, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[21]" LOC = "P9"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[2].strobe/fifo_bit5" LOC = SLICE_X2Y68; |
INST "*/data_path0/data_read0/gen_strobe[2].strobe_n/fifo_bit5" LOC = SLICE_X2Y69; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 20, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[20]" LOC = "P8"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[2].strobe/fifo_bit4" LOC = SLICE_X0Y68; |
INST "*/data_path0/data_read0/gen_strobe[2].strobe_n/fifo_bit4" LOC = SLICE_X0Y69; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 23, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[23]" LOC = "R6"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[2].strobe/fifo_bit7" LOC = SLICE_X2Y70; |
INST "*/data_path0/data_read0/gen_strobe[2].strobe_n/fifo_bit7" LOC = SLICE_X2Y71; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 22, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[22]" LOC = "R5"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[2].strobe/fifo_bit6" LOC = SLICE_X0Y70; |
INST "*/data_path0/data_read0/gen_strobe[2].strobe_n/fifo_bit6" LOC = SLICE_X0Y71; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 25, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[25]" LOC = "P6"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[3].strobe/fifo_bit1" LOC = SLICE_X2Y74; |
INST "*/data_path0/data_read0/gen_strobe[3].strobe_n/fifo_bit1" LOC = SLICE_X2Y75; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 24, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[24]" LOC = "P7"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[3].strobe/fifo_bit0" LOC = SLICE_X0Y74; |
INST "*/data_path0/data_read0/gen_strobe[3].strobe_n/fifo_bit0" LOC = SLICE_X0Y75; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 27, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[27]" LOC = "T4"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[3].strobe/fifo_bit3" LOC = SLICE_X2Y76; |
INST "*/data_path0/data_read0/gen_strobe[3].strobe_n/fifo_bit3" LOC = SLICE_X2Y77; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 26, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[26]" LOC = "T3"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[3].strobe/fifo_bit2" LOC = SLICE_X0Y76; |
INST "*/data_path0/data_read0/gen_strobe[3].strobe_n/fifo_bit2" LOC = SLICE_X0Y77; |
|
################################################################################################## |
## constraints for bit ddr2_dqs_n, 3, location in tile: 0 |
################################################################################################## |
NET "ddr2_dqs_n[3]" LOC = "R4"; #bank 3 |
|
################################################################################################## |
## constraints for bit ddr2_dqs, 3, location in tile: 0 |
################################################################################################## |
NET "ddr2_dqs[3]" LOC = "R3"; #bank 3 |
|
################################################################################################## |
## LUT location constraints for dqs_delayed_col0 |
################################################################################################## |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col0/one" LOC = SLICE_X2Y79; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col0/one" BEL = F; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col0/two" LOC = SLICE_X2Y79; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col0/two" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col0/three" LOC = SLICE_X2Y78; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col0/three" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col0/four" LOC = SLICE_X2Y78; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col0/four" BEL = F; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col0/five" LOC = SLICE_X3Y79; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col0/five" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col0/six" LOC = SLICE_X3Y78; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col0/six" BEL = G; |
|
################################################################################################## |
## LUT location constraints for dqs_delayed_col1 |
################################################################################################## |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col1/one" LOC = SLICE_X0Y79; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col1/one" BEL = F; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col1/two" LOC = SLICE_X0Y79; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col1/two" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col1/three" LOC = SLICE_X0Y78; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col1/three" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col1/four" LOC = SLICE_X0Y78; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col1/four" BEL = F; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col1/five" LOC = SLICE_X1Y79; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col1/five" BEL = G; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col1/six" LOC = SLICE_X1Y78; |
INST "*/data_path0/data_read_controller0/gen_delay[3].dqs_delay_col1/six" BEL = G; |
|
################################################################################################## |
## Slice location constraints for Fifo write address and write enable |
################################################################################################## |
INST "*/data_path0/data_read_controller0/gen_wr_addr[3].fifo_0_wr_addr_inst/bit0" LOC = SLICE_X1Y74; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[3].fifo_0_wr_addr_inst/bit1" LOC = SLICE_X1Y74; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[3].fifo_0_wr_addr_inst/bit2" LOC = SLICE_X1Y75; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[3].fifo_0_wr_addr_inst/bit3" LOC = SLICE_X1Y75; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[3].fifo_1_wr_addr_inst/bit0" LOC = SLICE_X3Y74; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[3].fifo_1_wr_addr_inst/bit1" LOC = SLICE_X3Y74; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[3].fifo_1_wr_addr_inst/bit2" LOC = SLICE_X3Y75; |
INST "*/data_path0/data_read_controller0/gen_wr_addr[3].fifo_1_wr_addr_inst/bit3" LOC = SLICE_X3Y75; |
#INST "*/data_path0/data_read_controller0/gen_wr_en[3].fifo_0_wr_en_inst" LOC = SLICE_X1Y77; |
INST "*/data_path0/data_read_controller0/gen_wr_en[3].fifo_0_wr_en_inst/dout*" LOC = SLICE_X1Y77; |
#INST "*/data_path0/data_read_controller0/gen_wr_en[3].fifo_1_wr_en_inst" LOC = SLICE_X3Y77; |
INST "*/data_path0/data_read_controller0/gen_wr_en[3].fifo_1_wr_en_inst/dout*" LOC = SLICE_X3Y77; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 29, location in tile: 0 |
################################################################################################## |
# Not correct! Schematic says P10 - Julius |
#NET "ddr2_dq[29]" LOC = "R2"; #bank 3 |
#INST "*/data_path0/data_read0/gen_strobe[3].strobe/fifo_bit5" LOC = SLICE_X2Y82; |
#INST "*/data_path0/data_read0/gen_strobe[3].strobe_n/fifo_bit5" LOC = SLICE_X2Y83; |
|
NET "ddr2_dq[29]" LOC = "P10"; #bank 3 |
|
################################################################################################## |
## constraints for bit ddr2_dq, 28, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[28]" LOC = "N9"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[3].strobe/fifo_bit4" LOC = SLICE_X0Y84; |
INST "*/data_path0/data_read0/gen_strobe[3].strobe_n/fifo_bit4" LOC = SLICE_X0Y85; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 31, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[31]" LOC = "P3"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[3].strobe/fifo_bit7" LOC = SLICE_X2Y86; |
INST "*/data_path0/data_read0/gen_strobe[3].strobe_n/fifo_bit7" LOC = SLICE_X2Y87; |
|
################################################################################################## |
## constraints for bit ddr2_dq, 30, location in tile: 0 |
################################################################################################## |
NET "ddr2_dq[30]" LOC = "P4"; #bank 3 |
INST "*/data_path0/data_read0/gen_strobe[3].strobe/fifo_bit6" LOC = SLICE_X0Y86; |
INST "*/data_path0/data_read0/gen_strobe[3].strobe_n/fifo_bit6" LOC = SLICE_X0Y87; |
|
################################################################################################## |
## constraints for bit rst_dqs_div_in, 1, location in tile: 1 |
################################################################################################## |
NET "ddr2_rst_dqs_div_in" LOC = "T9"; #bank 3 |
|
################################################################################################## |
## Slice location constraints for delayed rst_dqs_div signal |
################################################################################################## |
INST "*/data_path0/data_read_controller0/rst_dqs_div_delayed/one" LOC = SLICE_X0Y53; |
INST "*/data_path0/data_read_controller0/rst_dqs_div_delayed/one" BEL = F; |
INST "*/data_path0/data_read_controller0/rst_dqs_div_delayed/two" LOC = SLICE_X0Y52; |
INST "*/data_path0/data_read_controller0/rst_dqs_div_delayed/two" BEL = G; |
INST "*/data_path0/data_read_controller0/rst_dqs_div_delayed/three" LOC = SLICE_X0Y53; |
INST "*/data_path0/data_read_controller0/rst_dqs_div_delayed/three" BEL = G; |
INST "*/data_path0/data_read_controller0/rst_dqs_div_delayed/four" LOC = SLICE_X1Y52; |
INST "*/data_path0/data_read_controller0/rst_dqs_div_delayed/four" BEL = F; |
INST "*/data_path0/data_read_controller0/rst_dqs_div_delayed/five" LOC = SLICE_X1Y52; |
INST "*/data_path0/data_read_controller0/rst_dqs_div_delayed/five" BEL = G; |
INST "*/data_path0/data_read_controller0/rst_dqs_div_delayed/six" LOC = SLICE_X1Y53; |
INST "*/data_path0/data_read_controller0/rst_dqs_div_delayed/six" BEL = G; |
|
################################################################################################## |
## constraints for bit rst_dqs_div_out, 1, location in tile: 0 |
################################################################################################## |
NET "ddr2_rst_dqs_div_out" LOC = "T10"; #bank 3 |
|
################################################################################################## |
## Location constraint for rst_dqs_div_r flop in the controller. This is to be placed close the PAD |
## that drives the rst_dqs_div _out signal to meet the timing. |
################################################################################################## |
INST "*/controller0/rst_dqs_div_r" LOC = SLICE_X4Y52; |
################################################################################################## |
|
## DDR controller cache interface domain crossing timing ignores |
|
NET "wb_clk" TNM_NET = "WB_CLK"; |
NET "xilinx_s3adsp_ddr2/xilinx_s3adsp_ddr2_if/ddr2_if_clk" TNM_NET = "DDR2_IF_CLK"; |
|
# Path constraints - if bus clock is 50Mhz they have 20ns |
TIMESPEC TS_ddr2_controller_false_paths = FROM "WB_CLK" to "DDR2_IF_CLK" TIG; |
TIMESPEC TS_ddr2_controller_false_paths2 = FROM "DDR2_IF_CLK" to "WB_CLK" TIG; |
|
|
#### Module FLASH_16Mx8 constraints |
# Controller not present, so commenting out - Julius |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<31> LOC="AC23" | IOSTANDARD = LVCMOS33; # Flash A0 |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<30> LOC="AC24" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<29> LOC="R21" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<28> LOC="R22" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<27> LOC="T23" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<26> LOC="T24" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<25> LOC="R18" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<24> LOC="R17" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<23> LOC="R25" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<22> LOC="R26" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<21> LOC="M26" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<20> LOC="M25" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<19> LOC="L24" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<18> LOC="M23" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<17> LOC="N18" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<16> LOC="N17" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<15> LOC="N20" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<14> LOC="M20" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<13> LOC="J26" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<12> LOC="J25" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<11> LOC="J21" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<10> LOC="H21" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<9> LOC="C26" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_A_pin<8> LOC="C25" | IOSTANDARD = LVCMOS33; # Flash A23 |
#Net fpga_0_FLASH_16Mx8_Mem_DQ_pin<0> LOC="AE10" | IOSTANDARD = LVCMOS25; # Flash D7 |
#Net fpga_0_FLASH_16Mx8_Mem_DQ_pin<1> LOC="AF10" | IOSTANDARD = LVCMOS25; |
#Net fpga_0_FLASH_16Mx8_Mem_DQ_pin<2> LOC="AF12" | IOSTANDARD = LVCMOS25; |
#Net fpga_0_FLASH_16Mx8_Mem_DQ_pin<3> LOC="AE12" | IOSTANDARD = LVCMOS25; |
#Net fpga_0_FLASH_16Mx8_Mem_DQ_pin<4> LOC="Y15" | IOSTANDARD = LVCMOS25; |
#Net fpga_0_FLASH_16Mx8_Mem_DQ_pin<5> LOC="AF18" | IOSTANDARD = LVCMOS25; |
#Net fpga_0_FLASH_16Mx8_Mem_DQ_pin<6> LOC="AE18" | IOSTANDARD = LVCMOS25; |
#Net fpga_0_FLASH_16Mx8_Mem_DQ_pin<7> LOC="AF24" | IOSTANDARD = LVCMOS25; # Flash D0 |
#Net fpga_0_FLASH_16Mx8_Mem_WEN_pin LOC="Y20" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_OEN_pin<0> LOC="AE26" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_Mem_CEN_pin<0> LOC="AD25" | IOSTANDARD = LVCMOS33; |
#Net fpga_0_FLASH_16Mx8_rpn_dummy_pin LOC="N24" | IOSTANDARD = LVCMOS33; |
|
#### Module Ethernet_MAC constraints |
|
Net eth0_tx_er LOC="E4" | IOSTANDARD = LVCMOS18; # "Dummy" pin |
Net eth0_tx_clk LOC="P2" | IOSTANDARD = LVCMOS18; |
Net eth0_tx_en LOC="D3" | IOSTANDARD = LVCMOS18; |
Net eth0_tx_data<3> LOC="B1" | IOSTANDARD = LVCMOS18; |
Net eth0_tx_data<2> LOC="B2" | IOSTANDARD = LVCMOS18; |
Net eth0_tx_data<1> LOC="J9" | IOSTANDARD = LVCMOS18; |
Net eth0_tx_data<0> LOC="J8" | IOSTANDARD = LVCMOS18; |
|
Net eth0_crs LOC="G1" | IOSTANDARD = LVCMOS18; |
Net eth0_crs IOBDELAY=NONE; |
Net eth0_col LOC="Y3" | IOSTANDARD = LVCMOS18; |
Net eth0_col IOBDELAY=NONE; |
|
|
Net eth0_rx_clk LOC="P1" | IOSTANDARD = LVCMOS18; |
|
Net eth0_dv LOC="D1" | IOSTANDARD = LVCMOS18; |
Net eth0_dv IOBDELAY=NONE; |
Net eth0_rx_data<0> LOC="C2" | IOSTANDARD = LVCMOS18; |
Net eth0_rx_data<0> IOBDELAY=NONE; |
Net eth0_rx_data<1> LOC="G2" | IOSTANDARD = LVCMOS18; |
Net eth0_rx_data<1> IOBDELAY=NONE; |
Net eth0_rx_data<2> LOC="G5" | IOSTANDARD = LVCMOS18; |
Net eth0_rx_data<2> IOBDELAY=NONE; |
Net eth0_rx_data<3> LOC="D2" | IOSTANDARD = LVCMOS18; |
Net eth0_rx_data<3> IOBDELAY=NONE; |
Net eth0_rx_er LOC="J3" | IOSTANDARD = LVCMOS18; |
Net eth0_rx_er IOBDELAY=NONE; |
|
Net eth0_rst_n_o LOC="G4" | IOSTANDARD = LVCMOS18; |
|
Net eth0_mdc_pad_o LOC="F4" | IOSTANDARD = LVCMOS18; |
Net eth0_md_pad_io LOC="F5" | IOSTANDARD = LVCMOS18; |
|
#Net eth0_rx_clk PERIOD=40000 ps; |
Net eth0_rx_clk TNM_NET = eth0_rx_clk; |
TIMESPEC TS_eth0_rx_clk = PERIOD eth0_rx_clk 40000 ps; |
#Net eth0_tx_clk PERIOD=40000 ps; |
Net eth0_tx_clk TNM_NET = eth0_tx_clk; |
TIMESPEC TS_eth0_tx_clk = PERIOD eth0_tx_clk 40000 ps; |
|
###################################################################################3 |
# EXP Expansion Connector JX1 |
|
# JX1 - Outputs: 36 Single-ended, 48 Differential (24 pairs) |
#NET se_o_grp1<0> LOC ="C22" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_0" |
#NET se_o_grp1<1> LOC ="A22" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_2" |
#NET se_o_grp1<2> LOC ="C21" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_4" |
#NET se_o_grp1<3> LOC ="B21" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_6" |
#NET se_o_grp1<4> LOC ="C20" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_8" |
#NET se_o_grp1<5> LOC ="B20" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_10" |
#NET se_o_grp1<6> LOC ="A20" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_12" |
#NET se_o_grp1<7> LOC ="D20" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_14" |
#NET se_o_grp1<8> LOC ="B19" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_16" |
#NET se_o_grp1<9> LOC ="A19" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_18" |
#NET se_o_grp1<10> LOC ="C18" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_20" |
#NET se_o_grp1<11> LOC ="B18" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_22" |
#NET se_o_grp1<12> LOC ="A18" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_24" |
#NET se_o_grp1<13> LOC ="C17" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_26" |
#NET se_o_grp1<14> LOC ="B14" | IOSTANDARD = LVCMOS25; # "EXP1_DIFF_CLK_IN_P" |
#NET se_o_grp1<15> LOC ="A14" | IOSTANDARD = LVCMOS25; # "EXP1_DIFF_CLK_IN_N" |
#NET se_o_grp1<16> LOC ="D17" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_30" |
#NET se_o_grp1<17> LOC ="B17" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_31" |
#NET se_o_grp1<18> LOC ="G20" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_1" |
#NET se_o_grp1<19> LOC ="G19" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_3" |
#NET se_o_grp1<20> LOC ="E21" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_5" |
#NET se_o_grp1<21> LOC ="D23" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_7" |
#NET se_o_grp1<22> LOC ="B23" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_9" |
#NET se_o_grp1<23> LOC ="C23" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_11" |
#NET se_o_grp1<24> LOC ="D22" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_13" |
#NET se_o_grp1<25> LOC ="D21" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_15" |
#NET se_o_grp1<26> LOC ="F20" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_17" |
#NET se_o_grp1<27> LOC ="H17" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_19" |
#NET se_o_grp1<28> LOC ="F19" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_21" |
#NET se_o_grp1<29> LOC ="G17" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_23" |
#NET se_o_grp1<30> LOC ="K16" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_25" |
#NET se_o_grp1<31> LOC ="F17" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_27" |
|
#NET se_o_grp2<0> LOC ="D18" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_28" |
#NET se_o_grp2<1> LOC ="J14" | IOSTANDARD = LVCMOS25; # "EXP1_SE_CLK_IN" |
#NET se_o_grp2<2> LOC ="E17" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_29" |
#NET se_o_grp2<3> LOC ="G10" | IOSTANDARD = LVCMOS25; # "EXP1_SE_CLK_OUT" |
#NET se_o_grp2<4> LOC ="C16" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_32" |
#NET se_o_grp2<5> LOC ="J16" | IOSTANDARD = LVCMOS25; # "EXP1_SE_IO_33" |
# DIFF pair 10 is on "CC" I/O so have to make single-ended to be outputs |
#NET se_o_grp2<6> LOC ="C13" | IOSTANDARD = LVCMOS25; # "EXP1_DIFF_N10" |
#NET se_o_grp2<7> LOC ="B13" | IOSTANDARD = LVCMOS25; # "EXP1_DIFF_P10" |
|
#NET dp_o_grp3<0> LOC ="D6" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N0" |
#NET dp_o_grp3<1> LOC ="C6" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N2" |
#NET dp_o_grp3<2> LOC ="C7" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N4" |
#NET dp_o_grp3<3> LOC ="B8" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N6" |
#NET dp_o_grp3<4> LOC ="B9" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N8" |
#NET dp_o_grp3<5> LOC ="D10" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N12" |
#NET dp_o_grp3<6> LOC ="D11" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N14" |
#NET dp_o_grp3<7> LOC ="B4" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_CLK_OUT_N" |
#NET dp_o_grp3<8> LOC ="B12" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N16" |
#NET dp_o_grp3<9> LOC ="C12" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N18" |
#NET dp_o_grp3<10> LOC ="C15" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N20" |
#NET dp_o_grp3<11> LOC ="K11" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N1" |
#NET dp_o_grp3<12> LOC ="D8" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N3" |
#NET dp_o_grp3<13> LOC ="D9" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N5" |
#NET dp_o_grp3<14> LOC ="B10" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N7" |
#NET dp_o_grp3<15> LOC ="K12" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N9" |
|
#NET dp_o_grp3<16> LOC ="C5" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P0" |
#NET dp_o_grp3<17> LOC ="B6" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P2" |
#NET dp_o_grp3<18> LOC ="B7" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P4" |
#NET dp_o_grp3<19> LOC ="A8" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P6" |
#NET dp_o_grp3<20> LOC ="A9" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P8" |
#NET dp_o_grp3<21> LOC ="C10" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P12" |
#NET dp_o_grp3<22> LOC ="C11" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P14" |
#NET dp_o_grp3<23> LOC ="A4" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_CLK_OUT_P" |
#NET dp_o_grp3<24> LOC ="A12" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P16" |
#NET dp_o_grp3<25> LOC ="D13" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P18" |
#NET dp_o_grp3<26> LOC ="D16" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P20" |
#NET dp_o_grp3<27> LOC ="J11" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P1" |
#NET dp_o_grp3<28> LOC ="C8" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P3" |
#NET dp_o_grp3<29> LOC ="E10" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P5" |
#NET dp_o_grp3<30> LOC ="A10" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P7" |
#NET dp_o_grp3<31> LOC ="J12" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P9" |
|
#NET dp_o_grp4<0> LOC ="F12" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N11" |
#NET dp_o_grp4<1> LOC ="H12" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N13" |
#NET dp_o_grp4<2> LOC ="H15" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N15" |
#NET dp_o_grp4<3> LOC ="F14" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N17" |
#NET dp_o_grp4<4> LOC ="E15" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N19" |
#NET dp_o_grp4<5> LOC ="A15" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N21" |
|
#NET dp_o_grp4<6> LOC ="E12" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P11" |
#NET dp_o_grp4<7> LOC ="G12" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P13" |
#NET dp_o_grp4<8> LOC ="G15" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P15" |
#NET dp_o_grp4<9> LOC ="E14" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P17" |
#NET dp_o_grp4<10> LOC ="F15" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P19" |
#NET dp_o_grp4<11> LOC ="B15" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P21" |
|
# EXP Expansion Connector JX2 |
|
# JX2 - Inputs: 36 Single-ended, 48 Differential (24 pairs) |
#NET se_i_grp1<0> LOC ="V16" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_0" |
#NET se_i_grp1<1> LOC ="Y17" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_2" |
#NET se_i_grp1<2> LOC ="AA18" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_4" |
#NET se_i_grp1<3> LOC ="AC20" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_6" |
#NET se_i_grp1<4> LOC ="AA17" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_8" |
#NET se_i_grp1<5> LOC ="AC19" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_10" |
#NET se_i_grp1<6> LOC ="AB18" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_12" |
#NET se_i_grp1<7> LOC ="V15" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_14" |
#NET se_i_grp1<8> LOC ="W15" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_16" |
#NET se_i_grp1<9> LOC ="AB16" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_18" |
#NET se_i_grp1<10> LOC ="M21" | IOSTANDARD = LVCMOS33; # "EXP2_SE_IO_20" |
#NET se_i_grp1<11> LOC ="AC16" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_22" |
#NET se_i_grp1<12> LOC ="U22" | IOSTANDARD = LVCMOS33; # "EXP2_SE_IO_24" |
#NET se_i_grp1<13> LOC ="AC15" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_26" |
#NET se_i_grp1<14> LOC ="AA13" | IOSTANDARD = LVCMOS25; # "EXP2_DIFF_CLK_IN_P" |
#NET se_i_grp1<15> LOC ="Y13" | IOSTANDARD = LVCMOS25; # "EXP2_DIFF_CLK_IN_N" |
#NET se_i_grp1<16> LOC ="V14" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_30" |
#NET se_i_grp1<17> LOC ="U15" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_31" |
#NET se_i_grp1<18> LOC ="AE25" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_1" |
#NET se_i_grp1<19> LOC ="AF25" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_3" |
#NET se_i_grp1<20> LOC ="AE23" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_5" |
#NET se_i_grp1<21> LOC ="AF23" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_7" |
#NET se_i_grp1<22> LOC ="AD22" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_9" |
#NET se_i_grp1<23> LOC ="AE21" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_11" |
#NET se_i_grp1<24> LOC ="AD21" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_13" |
#NET se_i_grp1<25> LOC ="AC21" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_15" |
#NET se_i_grp1<26> LOC ="U23" | IOSTANDARD = LVCMOS33; # "EXP2_SE_IO_17" |
#NET se_i_grp1<27> LOC ="U24" | IOSTANDARD = LVCMOS33; # "EXP2_SE_IO_19" |
#NET se_i_grp1<28> LOC ="AD20" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_21" |
#NET se_i_grp1<29> LOC ="AF19" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_23" |
#NET se_i_grp1<30> LOC ="AE19" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_25" |
#NET se_i_grp1<31> LOC ="AD19" | IOSTANDARD = LVCMOS25; # "EXP2_SE_IO_27" |
|
#NET se_i_grp2<0> LOC ="R20" | IOSTANDARD = LVCMOS33; # "EXP2_SE_IO_28" |
#NET se_i_grp2<1> LOC ="AF13" | IOSTANDARD = LVCMOS25; # "EXP2_SE_CLK_IN" |
#NET se_i_grp2<2> LOC ="R19" | IOSTANDARD = LVCMOS33; # "EXP2_SE_IO_29" |
#NET se_i_grp2<3> LOC ="Y14" | IOSTANDARD = LVCMOS25; # "EXP2_SE_CLK_OUT" |
#NET se_i_grp2<4> LOC ="K23" | IOSTANDARD = LVCMOS33; # "EXP2_SE_IO_32" |
#NET se_i_grp2<5> LOC ="M22" | IOSTANDARD = LVCMOS33; # "EXP2_SE_IO_33" |
# DIFF pair 10 is on "CC" I/O so have to make single-ended to be outputs |
#NET se_i_grp2<6> LOC ="AE14" | IOSTANDARD = LVCMOS25; # "EXP2_DIFF_N10" |
#NET se_i_grp2<7> LOC ="AF14" | IOSTANDARD = LVCMOS25; # "EXP2_DIFF_P10" |
|
#NET dp_i_grp3<0> LOC ="AE6" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N0" |
#NET dp_i_grp3<1> LOC ="U11" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_N2" |
#NET dp_i_grp3<2> LOC ="Y9" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N4" |
#NET dp_i_grp3<3> LOC ="AA10" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N6" |
#NET dp_i_grp3<4> LOC ="AC9" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N8" |
#NET dp_i_grp3<5> LOC ="AC11" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N12" |
#NET dp_i_grp3<6> LOC ="W12" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N14" |
#NET dp_i_grp3<7> LOC ="V17" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_CLK_OUT_N" |
#NET dp_i_grp3<8> LOC ="AA12" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N16" |
#NET dp_i_grp3<9> LOC ="W13" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N18" |
#NET dp_i_grp3<10> LOC ="W10" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N20" |
#NET dp_i_grp3<11> LOC ="AF3" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N1" |
#NET dp_i_grp3<12> LOC ="AF4" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N3" |
#NET dp_i_grp3<13> LOC ="AB7" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N5" |
#NET dp_i_grp3<14> LOC ="AD6" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N7" |
#NET dp_i_grp3<15> LOC ="AE7" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N9" |
|
#NET dp_i_grp3<16> LOC ="AF5" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P0" |
#NET dp_i_grp3<17> LOC ="V11" | IOSTANDARD = LVDS_25; # "EXP1_DIFF_P2" |
#NET dp_i_grp3<18> LOC ="W9" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P4" |
#NET dp_i_grp3<19> LOC ="Y10" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P6" |
#NET dp_i_grp3<20> LOC ="AB9" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P8" |
#NET dp_i_grp3<21> LOC ="AD11" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P12" |
#NET dp_i_grp3<22> LOC ="V12" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P14" |
#NET dp_i_grp3<23> LOC ="W17" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_CLK_OUT_P" |
#NET dp_i_grp3<24> LOC ="Y12" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P16" |
#NET dp_i_grp3<25> LOC ="V13" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P18" |
#NET dp_i_grp3<26> LOC ="V10" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P20" |
#NET dp_i_grp3<27> LOC ="AE3" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P1" |
#NET dp_i_grp3<28> LOC ="AE4" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P3" |
#NET dp_i_grp3<29> LOC ="AC8" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P5" |
#NET dp_i_grp3<30> LOC ="AC6" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P7" |
#NET dp_i_grp3<31> LOC ="AD7" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P9" |
|
#NET dp_i_grp4<0> LOC ="AF8" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N11" |
#NET dp_i_grp4<1> LOC ="AF9" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N13" |
#NET dp_i_grp4<2> LOC ="AE20" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N15" |
#NET dp_i_grp4<3> LOC ="AD17" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N17" |
#NET dp_i_grp4<4> LOC ="AC12" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N19" |
#NET dp_i_grp4<5> LOC ="AC14" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_N21" |
|
#NET dp_i_grp4<6> LOC ="AE8" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P11" |
#NET dp_i_grp4<7> LOC ="AE9" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P13" |
#NET dp_i_grp4<8> LOC ="AF20" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P15" |
#NET dp_i_grp4<9> LOC ="AE17" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P17" |
#NET dp_i_grp4<10> LOC ="AB12" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P19" |
#NET dp_i_grp4<11> LOC ="AD14" | IOSTANDARD = LVDS_25; # "EXP2_DIFF_P21" |
|
#INST "jx1_to_jx2/jx1_to_jx2/nextbus_block/dp_i_grp3_ibufds*" DIFF_TERM = TRUE; |
#INST "jx1_to_jx2/jx1_to_jx2/nextbus_block/dp_i_grp4_ibufds*" DIFF_TERM = TRUE; |
|
#### DAC out |
#NET "CLK_25_175MHZ" LOC ="P26" | IOSTANDARD = LVCMOS33; |
#NET "DAC_HSYNC" LOC ="K26" | IOSTANDARD = LVCMOS33; |
#NET "DAC_VSYNC" LOC ="K25" | IOSTANDARD = LVCMOS33; |
#NET "DAC_RGB<0>" LOC ="L22" | IOSTANDARD = LVCMOS33; |
#NET "DAC_RGB<1>" LOC ="K21" | IOSTANDARD = LVCMOS33; |
#NET "DAC_RGB<2>" LOC ="G23" | IOSTANDARD = LVCMOS33; |
#NET "DAC_RGB<3>" LOC ="G24" | IOSTANDARD = LVCMOS33; |
#NET "DAC_RGB<4>" LOC ="M19" | IOSTANDARD = LVCMOS33; |
#NET "DAC_RGB<5>" LOC ="M18" | IOSTANDARD = LVCMOS33; |
#NET "DAC_RGB<6>" LOC ="J23" | IOSTANDARD = LVCMOS33; |
#NET "DAC_RGB<7>" LOC ="J22" | IOSTANDARD = LVCMOS33; |
#NET "DAC_RGB<8>" LOC ="L20" | IOSTANDARD = LVCMOS33; |
#NET "DAC_RGB<9>" LOC ="K20" | IOSTANDARD = LVCMOS33; |
#NET "DAC_RGB<10>" LOC ="F25" | IOSTANDARD = LVCMOS33; |
#NET "DAC_RGB<11>" LOC ="F24" | IOSTANDARD = LVCMOS33; |
|
#### Module SysACE_CompactFlash constraints |
|
#Net fpga_0_SysACE_CompactFlash_SysACE_CLK_pin LOC = AA14 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_CLK_pin TNM_NET = sysace_clk; |
#TIMESPEC TS_sysace_clk = PERIOD sysace_clk 41667 ps; |
|
#Net fpga_0_SysACE_CompactFlash_SysACE_MPA_pin<0> LOC = AC26 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPA_pin<1> LOC = AB26 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPA_pin<2> LOC = AB23 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPA_pin<3> LOC = AB24 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPA_pin<4> LOC = V18 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPA_pin<5> LOC = V19 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPA_pin<6> LOC = AA22 | IOSTANDARD = LVCMOS33; |
|
#Net fpga_0_SysACE_CompactFlash_SysACE_MPD_pin<0> LOC = AA23 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPD_pin<1> LOC = V21 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPD_pin<2> LOC = U20 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPD_pin<3> LOC = AA24 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPD_pin<4> LOC = AA25 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPD_pin<5> LOC = U19 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPD_pin<6> LOC = U18 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPD_pin<7> LOC = Y22 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPD_pin<8> LOC = Y23 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPD_pin<9> LOC = U21 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPD_pin<10> LOC = T20 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPD_pin<11> LOC = Y24 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPD_pin<12> LOC = Y25 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPD_pin<13> LOC = T18 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPD_pin<14> LOC = T17 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_MPD_pin<15> LOC = W23 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_CEN_pin LOC = V25 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_OEN_pin LOC = V22 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_WEN_pin LOC = V24 | IOSTANDARD = LVCMOS33; |
#Net fpga_0_SysACE_CompactFlash_SysACE_RST_pin LOC = V23 | IOSTANDARD = LVCMOS33; |
|
# Steal some pins off J8 (System Ace header) for debug connections to ORSoC debug cable |
|
|
NET uart0_srx_expheader_pad_i LOC = AA25; # J8 Pin 25, "D04" |
NET uart0_srx_expheader_pad_i TIG; |
NET uart0_srx_expheader_pad_i PULLUP; |
NET uart0_srx_expheader_pad_i IOSTANDARD = LVTTL; |
|
NET uart0_stx_expheader_pad_o LOC = U19; # J8 Pin 28, "D05" |
NET uart0_stx_expheader_pad_o TIG; |
NET uart0_stx_expheader_pad_o PULLUP; |
NET uart0_stx_expheader_pad_o IOSTANDARD = LVTTL; |
|
NET tdo_pad_o LOC = AA23; # J8 Pin 21, "D0" |
NET tdi_pad_i LOC = V21 ; # J8 Pin 24, "D1" |
NET tms_pad_i LOC = U20 ; # J8 Pin 23, "D2" |
NET tck_pad_i LOC = AA24; # J8 Pin 26, "D3" |
|
NET tdo_pad_o TIG; NET tdo_pad_o PULLUP; NET tdo_pad_o IOSTANDARD = LVTTL; |
NET tdi_pad_i TIG; NET tdi_pad_i PULLUP; NET tdi_pad_i IOSTANDARD = LVTTL; |
NET tms_pad_i TIG; NET tms_pad_i PULLUP; NET tms_pad_i IOSTANDARD = LVTTL; |
NET tck_pad_i TIG; NET tck_pad_i PULLUP; NET tck_pad_i IOSTANDARD = LVTTL; |
# Overide the following mapping error: |
# ERROR:Place:645 - A clock IOB clock component is not placed at an optimal clock |
# IOB site. |
NET "tck_pad_i" CLOCK_DEDICATED_ROUTE = FALSE; |
NET tck_pad_i TNM_NET = tck_pad_i; |
TIMESPEC TS_tck_pad_i = PERIOD tck_pad_i 40 ns; |
|
|
# SPI |
|
NET spi0_mosi_o LOC = AB15 | IOSTANDARD = LVCMOS33 | DRIVE = 6 | SLEW = FAST | TIG; |
NET spi0_ss_o<0> LOC = AA7 | IOSTANDARD = LVCMOS33 | DRIVE = 6 | SLEW = FAST | TIG; |
NET spi0_miso_i LOC = AF24 | IOSTANDARD = LVCMOS33 | DRIVE = 6 | SLEW = FAST | TIG; |
NET spi0_sck_o LOC = AE24 | IOSTANDARD = LVCMOS33 | DRIVE = 6 | SLEW = FAST | TIG; |
/s3adsp1800/backend/par/bin/Makefile
0,0 → 1,151
###################################################################### |
#### #### |
#### ORPSoC Xilinx backend Makefile #### |
#### #### |
#### Author(s): #### |
#### - Julius Baxter, julius@opencores.org #### |
#### #### |
#### #### |
###################################################################### |
#### #### |
#### Copyright (C) 2009,2010,2011 Authors and 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 #### |
#### #### |
###################################################################### |
|
# Name of the directory we're currently in |
CUR_DIR=$(shell pwd) |
|
# The root path of the board build |
BOARD_ROOT ?=$(CUR_DIR)/../../.. |
include $(BOARD_ROOT)/Makefile.inc |
|
# |
# Options for Xilinx PAR tools |
# |
FPGA_PART=xc3sd1800a-fg676-4 |
XILINX_FLAGS=-intstyle silent |
XILINX_MAP_FLAGS=-logic_opt off |
XILINX_AREA_TARGET = speed |
TIMING_REPORT_OPTIONS = -u 1000 -e 1000 |
SPI_FLASH_SIZE_KBYTES ?=8192 |
SPI_BOOTLOADER_SW_OFFSET_HEX ?=7c0000 |
|
print-config: |
$(Q)echo; echo "\t### Backend make configuration ###"; echo |
$(Q)echo "\tFPGA_PART="$(FPGA_PART) |
$(Q)echo "\tXILINX_FLAGS="$(XILINX_FLAGS) |
$(Q)echo "\tXILINX_MAP_FLAGS="$(XILINX_MAP_FLAGS) |
$(Q)echo "\tXILINX_AREA_TARGET="$(XILINX_AREA_TARGET) |
$(Q)echo "\tTIMING_REPORT_OPTIONS="$(TIMING_REPORT_OPTIONS) |
$(Q)echo "\tSPI_FLASH_SIZE_KBYTES="$(SPI_FLASH_SIZE_KBYTES) |
$(Q)echo "\tSPI_BOOTLOADER_SW_OFFSET_HEX="$(SPI_BOOTLOADER_SW_OFFSET_HEX) |
|
NGC_FILE=$(BOARD_SYN_RUN_DIR)/$(DESIGN_NAME).ngc |
NGD_FILE=$(DESIGN_NAME).ngd |
UCF_FILE=../bin/$(BOARD_NAME).ucf |
MAPPED_NCD=$(DESIGN_NAME)_mapped.ncd |
PARRED_NCD=$(DESIGN_NAME).ncd |
PCF_FILE=$(DESIGN_NAME).pcf |
BIT_FILE=$(DESIGN_NAME).bit |
BIT_FILE_FOR_SPI=$(DESIGN_NAME)_spiboot.bit |
BATCH_FILE=$(DESIGN_NAME).batch |
MCS_FILE=$(DESIGN_NAME).mcs |
|
$(NGC_FILE): |
$(Q)$(MAKE) -C $(BOARD_SYN_RUN_DIR) $(DESIGN_NAME).ngc |
|
$(NGD_FILE): $(UCF_FILE) $(NGC_FILE) |
@echo; echo "\t#### Running NGDBuild ####"; |
$(Q)( . $(XILINX_SETTINGS_SCRIPT) && \ |
ngdbuild -p $(FPGA_PART) -sd $(BOARD_BACKEND_BIN_DIR) -uc $(UCF_FILE) \ |
$(NGC_FILE) $@ ) |
|
#This target uses Xilinx tools to perform Mapping |
$(MAPPED_NCD): $(NGD_FILE) |
@echo; echo "\t#### Mapping ####"; |
$(Q)( . $(XILINX_SETTINGS_SCRIPT) && \ |
export XIL_MAP_NO_DSP_AUTOREG=1 && \ |
export XIL_MAP_ALLOW_ANY_DLL_INPUT=1 && \ |
map -p $(FPGA_PART) -detail -pr b -cm ${XILINX_AREA_TARGET} \ |
-timing -ol high -w $(XILINX_FLAGS) -o $@ -xe n $(NGD_FILE) $(PCF_FILE)) |
|
#This target uses Xilinx tools to Place & Route the design |
$(PARRED_NCD): $(MAPPED_NCD) |
@echo; echo "\t#### PAR'ing ####"; |
$(Q)( . $(XILINX_SETTINGS_SCRIPT) && \ |
par -w -ol high $(XILINX_FLAGS) $< $@ $(PCD_FILE) ) |
|
#This target uses Xilinx tools to generate a bitstream for download |
$(BIT_FILE): $(PARRED_NCD) |
@echo; echo "\t#### Generating .bit file ####"; |
$(Q)( . $(XILINX_SETTINGS_SCRIPT) && \ |
bitgen -w $(XILINX_FLAGS) -g StartUpClk:JtagClk $< $@ ) |
|
$(BIT_FILE_FOR_SPI): $(PARRED_NCD) |
@echo; echo "\t#### Generating .bit file for SPI load ####"; |
$(Q)( . $(XILINX_SETTINGS_SCRIPT) && \ |
bitgen -w $(XILINX_FLAGS) -g StartUpClk:CClk $< $@ ) |
|
# Generate MCS with bootloader specified by user, if BOOTLOADER_BIN defined. |
ifeq ($(BOOTLOADER_BIN),) |
$(MCS_FILE): $(BIT_FILE_FOR_SPI) |
@echo; echo "\t#### Generating .mcs file for SPI load ####"; |
$(Q)( . $(XILINX_SETTINGS_SCRIPT) && \ |
promgen -spi -p mcs -w -o $@ -s $(SPI_FLASH_SIZE_KBYTES) -u 0 $< ) |
else |
$(MCS_FILE): $(BIT_FILE_FOR_SPI) |
@echo; echo "\t#### Generating .mcs file with bootloader for SPI load ####"; |
$(Q)( . $(XILINX_SETTINGS_SCRIPT) && \ |
promgen -spi -p mcs -w -o $@ -s $(SPI_FLASH_SIZE_KBYTES) -u 0 $< \ |
-data_file up $(SPI_BOOTLOADER_SW_OFFSET_HEX) $(BOOTLOADER_BIN) \ |
) |
endif |
|
#this target downloads the bitstream to the target fpga |
download: $(BIT_FILE) $(BATCH_FILE) |
$(Q)( . $(XILINX_SETTINGS_SCRIPT) && \ |
impact -batch $(BATCH_FILE) ) |
|
#This target uses netgen to make a simulation netlist |
netlist: $(PARRED_NCD) |
@echo; echo "\t#### Generating netlist ####"; |
$(Q)(. $(XILINX_SETTINGS_SCRIPT) && \ |
netgen -ofmt verilog -sim -dir netlist -pcf $(PCF_FILE) $<) |
|
#This one uses TRCE to make a timing report |
timingreport: $(PARRED_NCD) |
@echo; echo "\t#### Generating timing report ####"; |
$(Q)(. $(XILINX_SETTINGS_SCRIPT) && \ |
trce $(TIMING_REPORT_OPTIONS) $< ) |
|
|
clean: |
$(Q)rm -rf *.* xlnx_auto* _xmsgs |
|
clean-syn: |
$(Q)$(MAKE) -C $(BOARD_SYN_RUN_DIR) distclean |
|
distclean: clean-syn clean |
|
.PRECIOUS : $(PARRED_NCD) $(MAPPED_NCD) $(NGC_FILE) $(NGD_FILE) $(BIT_FILE) $(BIT_FILE_FOR_SPI) |
/s3adsp1800/backend/bin/s3adsp_ddr2_cache.ngc
0,0 → 1,3
XILINX-XDB 0.1 STUB 0.1 ASCII |
XILINX-XDM V1.6e |
$37244<,[o}e~g`n;"2*736(-30<=>?0123416<89:;<=>?0123456789:;<=>?0123456789:;<=>?0123456789:;<=>?012345679:1:<7GAPTV9eabui531<3?;;069MKVR\3KOH_O31283:42<9=0BB][[:@FGVG:6;3:5=?5<2;KMTPR=L@K7?<4?>00877<NFY__6IGM<2394;743:81EC^ZT;fjjd:493:5=>5<2;MVPUSS2MEJ0>?50?30?64=G\^[YY4KOC>05?699<18>7AZTQWW>air|h68=7>1f:1p`4>78hll::8"40380?OIX\^1HD^N<283:47<<3CE\XZ5DHRA86<768:087GAPTV9S@G;;3:5==5;:HLSQQ<PMK686=0>0:69MKVR\3}nm1=50?31?1<H]]Z^X7J@P@>0>586:2>1CXZ_UU8GKUD;;3:5=>594;KMTPR=l`di0;=50?36?32=G\^[YY4kotva835=87;;754FNQWW>rce4>0;2<<49;KMTPR=imnyn1650?:8EABUI5:556OKDSC?558>3HNO^L2>1?;8EABUI5;92o5NDEPB845=8730MIJ]A=30:==FLMXJ0<07;@FGVD:5611JHI\N<2<;?DBCZH6?255NDEPB808?3HNO^L29>99B@ATF4>437LJKR@>;:==FLMXJ0407;@FGVG:7601JHI\M<02==>GCL[H7=<06;@FGVG:6:7h0MIJ]B=30>58>3HNO^O2>3?:8EABUJ5;546OKDS@?6;><IMNYN1=18:CG@WD;<720MIJ]B=7=<>GCL[H7:364AEFQF91902KOH_L38?:8EABUJ53546LZS^KMBJ4<KL;97NFJCJ]OMFCI[LU_U]K;;BNHE1=DDBH27NABMHVWAA733JEYIRIJNDPBPLIIW@DMC:5LRDCWAAe<LH^JSZGKTI]Bg>BF\HU\EIZG_C48@LG;87=0HDO311<4?AOF48;5;6JFA=31:2=CAH6:?394DHC?51803MCJ0<;17:FJE9716>1OEL2>7?58@LG;914<7IGN<0;=2>BNI5;5;6JFA=03:2=CAH69=394DHC?67803MCJ0?=17:FJE9436>1OEL2=5?58@LG;:?4<7IGN<35=3>BNI5832:5KI@>1=;0<L@K7>394DHC?758>3MCJ0>?50?58@LG;;84=7IGN<2<5?AOF4=4=7IGN<4<5?AOF4?4=7IGN<6<5?AOF414=7IGN<8<5?AOE494<7IGM<02=3>BNJ5;:2:5KIC>26;1<L@H7=>08;EKA8429?2NBN1?:>69GMG:6>7=0HDL316<4?AOE4825;6JFB=3::3=CAK6:2:5KIC>14;1<L@H7><08;EKA8749?2NBN1<<>69GMG:5<7=0HDL324<4?AOE4;<5;6JFB=04:2=CAK694394DH@?6<813MCI0?08;EKA866912NBN1=>:1<4?AOE4:;5:6JFB=1=2>BNJ5>5:6JFB=7=2>BNJ5<5:6JFB=5=2>BNJ525:6JFB=;=3>BNXH6;2:5KIQC?5;1<L@ZJ0?06;EKSE95=87=0HD^N<2<4?AOWJ5:5;6JFPC>2:2=CAYH7>374DHRA86<76>1OE]L33?48@JG;87=0HBO311<4?AIF48;5;6J@A=31:2=CGH6:?394DNC?51803MEJ0<;17:FLE9716>1OCL2>7?58@JG;914<7IAN<0;=2>BHI5;5;6J@A=03:2=CGH69=394DNC?67803MEJ0?=17:FLE9436>1OCL2=5?58@JG;:?4<7IAN<35=3>BHI5832:5KO@>1=;0<LFK7>394DNC?758>3MEJ0>?50?58@JG;;84=7IAN<2<5?AIF4=4=7IAN<4<5?AIF4?4=7IAN<6<5?AIF414=7IAN<8<4?AIFW[OL:6J@B=2=3>BHJ5;;2:5KOC>25;1<LFH7=?08;EMA8459?2NDN1?;>69GKG:6=7=0HBL317<4?AIE48=5;6J@B=3;:2=CGK6:5384DN@?5;1<LFH7>=08;EMA8779?2NDN1<=>69GKG:5;7=0HBL325<4?AIE4;?5;6J@B=05:2=CGK69;394DN@?6=803MEI0?716:FLF949?2NDN1=?>89GKG:493:5;6J@B=12:3=CGK682;5KOC>7:3=CGK6>2;5KOC>5:3=CGK6<2;5KOC>;:3=CGK622:5KOC]QAB1<LFZJ0=08;EMSE979?2ND\L2=>89GKUG;;3:5;6J@P@>0:2=CGYH7<394DNRA84803ME[N1<19:FLTG:4294<7IA_B=1=7>CII:1NBOl4EO]QWQTFEVKi7H@PRRVQEHYE92M87J@K8:KMMQVX8920ECG[P^22<>OIA]ZT<?64IOKWTZ6402CEEY^P05:8MKOSXV:>46GAIUR\43><AGC_\R>87:KMMQY78>1BBDZP0058MKOSW98<7D@FT^203>OIA]U;8:5FNHV\401<AGC_S=88;HLJPZ60?2CEEYQ?869JJLRX80=0ECG[_1C4?LHN\V:I;6GAIU]3G2=NF@^T<I94IOKW[5C03@DBXR>I7:KMMQY68>1BBDZP1058MKOSW88<7D@FT^303>OIA]U:8:5FNHV\501<AGC_S<88;HLJPZ70?2CEEYQ>869JJLRX90=0ECG[_0C4?LHN\V;I;6GAIU]2G2=NF@^T=I94IOKW[4C03@DBXR?I7:KMMQY58>1BBDZP2058MKOSW;8<7D@FT^003>OIA]U98:5FNHV\601<AGC_S?88;HLJPZ40?2CEEYQ=869JJLRX:0=0ECG[_3C4?LHN\V8I;6GAIU]1G2=NF@^T>I94IOKW[7C03@DBXR<I7:KMMQY48>1BBDZP3058MKOSW:8<7D@FT^103>OIA]U88:5FNHV\701<AGC_S>88;HLJPZ50?2CEEYQ<869JJLRX;0=0ECG[_2C4?LHN\V9I;6GAIU]0G2=NF@^T?I94IOKW[6C03@DBXR=I6:KMMQYF>2CEEYQM9:KMMQYAAEO=7AANDDF4?II@AJKGo6CnjnpUawunggi0Ad``rWgqwlii:2D;;6@JTVMQO1=IGGO<7B ;0e]O0>VFZ]k0\D@PBTQJ@]d<X@DTNX]AALGb?WGJJ8<I[H\9;SGDG@G13[OLOHL;;SQWE1=U[]H<7_][TXRFa>TT\VZYEB\FTX]Ba>TT\VZYEB\FTX]A56=TADUHCABFSHMM[FNBKBk0_DCPDDTJG@0<[F_YOHm4SQCQPDH4IMY[;6]]V@N\E2=TZ_KGSO:4SXL@0>RU]L>0XT^J6d9V4*~t|VhggRcjm^efj`tf|fx$kco{iwgaib(ii}c}iRlck^ofiZabf&|j`dj!crvq+wgjdfe{W=S!r`o-v*u4imy{Scafnhv-vdk(lyxja#|nm7g8Q5){}Ui`fQbel]dakcui}ey#j`nthtffha)fh~bzhQmlj]nahY`mg%}magk.bqwv*tfeeed|V?R.scn*w)t;hnx|R``iokw*wgj'mzym` }ala8QVCUW_CXEOBJ9:TJARYSQYO=7ZKN<1<5?RCF484=7ZKN<3<;?RCF4:0;2;5XE@>0:3=PMK6;2;5XEC>2:3=PMK69255XEC>0>5813^OI0>0m;VPJP@YAA[Y_o6Y]IUG\IJBBWHi0[_G[E^OL@@YE9m1SEAGAX,ZGF%6)9)Y_YO.?.0"BWFON>2RXXAGM7:ZPPZAILk1SSNA]E^KMBJ0<PmhTEih4Xej\Twoj^lxxeb`>0:ZgiZKfbfx]i}foo33?]bjWDcecXjrrklj6=_{}20mij}a=2=<>gcl{k7=364aefqe94902koho33?:8eabui5>546okdsc?1;><imnym1818:cg`wg;?720mij}a=:=e>gcl{k757>18:cg`wg;1720mij}b=2=<>gcl{h7=364aefqf94902kohl33?:8eabuj5>546okds`?1;><imnyn1818:cg`wd;?7k0mij}b=:94;><imnyn1612b9ahnYjmdUlicQy6^3/$]okagr+OB\J Fgmawgsg{*:?#?;;bnhe1=ddbh<7igaa=2=<>bnfh6:<364dhlb847902nbbl2>2?:8`lhf489546jfn`>20;><l`dj0<;18:fjjd:6>720hd`n<05=<>bnfh6:4364dhlb84?9?2nbbl2>>99gmkg;:9437igaa=02:==cagk7>?07;ekme944611oeco325<;?aoii58>255kioc?638?3mcem1<8>99gmkg;:1437igaa=0::2=cagk7>364dhlb8669i2nbbl2<1;2=<>bnfh68=394dhlb86803mcem1:17:fjjd:26>1oeco36?58`lhf4>4<7igaa=:=3>bnfh622:5kio`?4;><l`di0<>18:fjjg:69720hd`m<00=<>bnfk6:?364dhla842902nbbo2>5?:8`lhe48<546jfnc>23;><l`di0<618:fjjg:617=0hd`m<0<;?aoij58;255kio`?648?3mcen1<=>99gmkd;::437igab=07:==cagh7>807;ekmf941611oecl326<;?aoij583255kio`?6<803mcen1<18:fjjg:48720hd`m<23=<>bnfk68>364dhla865902nbbo2<4?:8`lhe4:?546jfnc>02;><l`di0>918:fjjg:40720hd`m<2;=3>bnfk68255kio`?058?3mcen1:>>99gmkd;<;437igab=60:==cagh78907;ekmf922611oecl347<;?aoij5><255kio`?0=8?3mcen1:6>69gmkd;<720hd`m<42=<>bnfk6>=364dhla804902nbbo2:3?:8`lhe4<>546jfnc>61;><l`di08818:fjjg:2?720hd`m<4:=<>bnfk6>5394dhla808?3mcen18?>99gmkd;>8437igab=41:d=cagh7:>4?>99gmkd;>:4<7igab=4=3>bnfk6<2:5kio`?<;1<l`di0407;emvpd:7601ocxzn<02==>bh}}k7=<06;emvpd:6:730hb{{a=30:<=cg|~j0<:19:flqqg;9<427iazt`>22;?<lfm1?8>89gkprf482556j`uuc?5<8?3me~xl2>>89gkprf4;:556j`uuc?648>3me~xl2=2?;8`jssi588245kotvb872912ndyyo324<:?air|h69:374dnwwe940601ocxzn<3:==>bh}}k7>407;emvpd:5601ocxzn<22=f>bh}}k7?<4?>89gkprf4:;546j`uuc?7;><lfm1:18:flqqg;=720hb{{a=4=<>bh}}k7;364dnwwe9>902ndyyo39?:8`jssj5:556j`uu`?558>3me~xo2>1?;8`jssj5;9245kotva845912ndyyl315<:?air|k6:9374dnwwf971601ocxzm<05==>bh}}h7=506;emvpg:61720hb{{b=3==>bh}}h7>=06;emvpg:59730hb{{b=01:<=cg|~i0?=19:flqqd;:=427iaztc>11;?<lfn1<9>89gkpre4;=556j`uu`?6=8>3me~xo2=9?:8`jssj58556j`uu`?758>3me~xo2<1?;8`jssj599245kotva865912ndyyl335<:?air|k689374dnwwf951601ocxzm<25==>bh}}h7?506;emvpg:41720hb{{b=1==>bh}}h78=06;emvpg:39730hb{{b=61:<=cg|~i09=19:flqqd;<=427iaztc>71;?<lfn1:9>89gkpre4==556j`uu`?0=8>3me~xo2;9?:8`jssj5>556j`uu`?158>3me~xo2:1?;8`jssj5?9245kotva805912ndyyl355<:?air|k6>9374dnwwf931601ocxzm<45==>bh}}h79506;emvpg:21720hb{{b=7==>bh}}h7:=06;emvpg:19730hb{{b=41:g=cg|~i0;=50?;8`jssj5<8255kotva838?3me~xo28>99gkpre41437iaztc>::6=bfh90icl7;oe`fpokl8;0>oksq]g`w4Xkhici?m4s2cgwuYcl{8Tolmge-`ooZkbeVmnbRx9_0.MKKC+FFDN84>4s2cgwuYcl{8Tolmge-`ooZkbeVmnbRx9_0.xgZgcl{kT{dj{h<33(fYflmxiSzgkti?:(fYfdneyeyfb=0.`[d~nW`nT{dj{h<6/gZgaVygm{kPtxrf95*dWhrbSywe<3/gZd~|lUxewk28-a\gjkjggUh`f3?,b]gacgrd}Uomyo20-a\`lufjeoT{l|a_cju[fikd4;'oRjfs``oaZqfzgUid{Q}aoef95*dWlfjnb|nthmm[aou5&~f|"zbp.]`c*)+kVljadbv=rrbvqgi;%iTdl}Payk\ma;7$jUcm~Qjn`?2(fYoizUnbo3>,b]kevYnfcohxh|}=1.`[mgtWdofSb{{ptv\v`atWh7; nQgar]nahYh}}z~xR|jgr]a95*dWakxS`{w_nwwtprXzlmxSl3?,b]kevYj}qUdyy~zt^pfcvYe59&hSeo|_sgdg`g:8%iTdl}Prde`ag;7$jUcm~Q}suc>4)eX`hyT~~zm=1.`[mgtWzemxhml_hlsqqYumnyTm0>#c^jbwZuhn}ohoRaztqww[wc`{Vh6<!mPiokw[cokmVdjah3ao^alaZ`ndlUgcljjd-a\mkosiV|j`0>#c^kmmqdX~hf6<!mPiovfvcgdmV~r|h3?,b]okdbXagcSkgce<2/gZkbeV~r|h3=,b]nq}YwayogeckPsucdav;7$jU{~dcPtxrf94*dW{ojhRjjpuj\e877:=&hSknd^fftqnXj4?:>!mPrdcg[roc|aUj1><#c^pfeaYpam~cSo394-a\vvrXx{cd~dzv_`?@A)eXzz~T|g`rhvz[g;DM%iT~~zPtxrf9V_IK%iT~~z}al]b95*dW{y~lcPb<2/gZuneVid`ag|inl\gmcdc4DDBH"l_tqf[gsmV}nm0?#c^wpaZd~|lU|io3>,b]vw`Ycmok~`yQkauc>4)eX}zoTinm20-a\qvcX{flinm20-a\s`gX`nd0:#c^uffZqnl}b64!mPwskwaZbbx}bTm0??25.`[rtn|lUoi}zg_c?657*dW~xbxhQboeg\e8QUA]OTJD\\T-a\swosmVgdhhQm=VPJP@YAA[Y_ nQxrhvf[roc|aUj1><#c^uqmqcX`ndRl265.`[}bb~`injlcflx?ptdtsig9jh~~r6:ufe969>2}nm1?16:ufe94902}nm1=50?48s`g;;7<0{hl30?48s`d;97<0{hl32?48s`d;;7<0{hl34?48s`d;=7<0{hl36?:8s`d;?3:5:6yjb=5=yEFw<:80LMv=418E>1<6sZ9o6<8?:011>455lm8;6<8826ym50c=92d:9k49;%36g?7202wX?o4>618277<6;;no>=4>660`?V75j388j7>5120g`76=9?=896]<b;00b?6=9:8oh?>517502>b5<90;6<4>{R1g>40728996<==de03>400:j1}X<:?:182>4<b<rY8h7?90;306?74:mn9<7?973a8 42f288h7[?:d;0xq44c281~=?k50:'565=k2h98=4?:d197?c3sA;?56*>478105=];?03wo4>5;32>40=;3;<654>4;'50d=9><0(>652538 6e=:=80e?=k:188m75b2900e<98:188m41?2900c<h;:18'563=9o90b<=;:198k4`5290/=>;51g18j4532810c<h?:18'563=9o90b<=;:398k4ca290/=>;51g18j4532:10c<kj:18'563=9o90b<=;:598k4cc290/=>;51g18j4532<10c<kl:18'563=9o90b<=;:798k4ce290/=>;51g18j4532>10c<kn:18'563=9o90b<=;:998k4c>290/=>;51g18j4532010c<k7:18'563=9o90b<=;:`98k4c0290/=>;51g18j4532k10c<k::18'563=9o90b<=;:b98k4c3290/=>;51g18j4532m10c<k<:18'563=9o90b<=;:d98k4c5290/=>;51g18j4532o10c<k>:18'563=9o90b<=;:028?j7b83:1(<=::0d0?k74<3;:76a>dg83>!74=3;m?6`>35826>=h9mo1<7*>3482b6=i9:>1=>54o0fg>5<#9:?1=k=4n017>42<3f;oo7>5$016>4`43g;887?:;:m2bg<72-;897?i3:l271<6>21d=ko50;&270<6n:1e=>:51698k4`>290/=>;51g18j45328207b?i8;29 45228l87c?<4;3:?>i6n>0;6)?<5;3e7>h6;=0:m65`1g494?"6;<0:j>5a12695g=<g8l>6=4+12795c5<f89?6<m4;n3e5?6=,89>6<h<;o300?7c32e:i;4?:%301?7a;2d:?94>e:9l5ad=83.:?84>f29m562=9o10c?=7:18'563=::=0b<=;:198k751290/=>;52258j4532810c?=::18'563=::=0b<=;:398k753290/=>;52258j4532:10c?==:18'563=::=0b<=;:598k756290/=>;52258j4532<10c?=?:18'563=::=0b<=;:798k74a290/=>;52258j4532>10c?<j:18'563=::=0b<=;:998k74c290/=>;52258j4532010c?<l:18'563=::=0b<=;:`98k74e290/=>;52258j4532k10c?<n:18'563=::=0b<=;:b98k74>290/=>;52258j4532m10c?<8:18'563=::=0b<=;:d98k741290/=>;52258j4532o10c?<::18'563=::=0b<=;:028?j45<3:1(<=::314?k74<3;:76a=2283>!74=388;6`>35826>=h:;81<7*>348172=i9:>1=>54o302>5<#9:?1>>94n017>42<3f89<7>5$016>7503g;887?:;:m15c<72-;897<<7:l271<6>21d><k50;&270<5;>1e=>:51698k77d290/=>;52258j45328207b<>b;29 4522;9<7c?<4;3:?>i59h0;6)?<5;003>h6;=0:m65`20;94?"6;<09?:5a12695g=<g;;36=4+1279661<f89?6<m4;n023?6=,89>6?=8;o300?7c32e9=;4?:%301?44?2d:?94>e:9l643=83.:?84=369m562=9o10c??;:18'563=::=0b<=;:328?j46;3:1(<=::314?k74<38:76a=1083>!74=388;6`>35816>=h:8:1<7*>348172=i9:>1>>54o32e>5<#9:?1>>94n017>72<3f8;i7>5$016>7503g;887<:;:m14a<72-;897<<7:l271<5>21d>=m50;&270<5;>1e=>:52698k76e290/=>;52258j4532;207b<?a;29 4522;9<7c?<4;0:?>i5800;6)?<5;003>h6;=09m65`21:94?"6;<09?:5a12696g=<g;:=6=4+1279661<f89?6?m4;n031?6=,89>6?=8;o300?4c32e9<94?:%301?44?2d:?94=e:9l655=83.:?84=369m562=:o10c?>=:18'563=::=0b<=;:228?j4793:1(<=::314?k74<39:76a=0183>!74=388;6`>35806>=h9ol1<7*>348172=i9:>1?>54o0df>5<#9:?1>>94n017>62<3f;mh7>5$016>7503g;887=:;:m17f<72-;897<<7:l271<4>21d>>l50;&270<5;>1e=>:53698k75f290/=>;52258j4532:207b<<9;29 4522;9<7c?<4;1:?>i5;:0;6)?<5;003>h6;=08m65`23:94?"6;<09?:5a12697g=<g;;o6=4+1279661<f89?6>m4;n026?6=,89>6?=8;o300?5c32e9<:4?:%301?44?2d:?94<e:9l5ce=83.:?84=369m562=;o10e?:8:18'563=:=<0b<=;:198m722290/=>;52548j4532810e?:;:18'563=:=<0b<=;:398m724290/=>;52548j4532:10e?;?:18'563=:=l0b<=;:198m72b290/=>;525d8j4532810e?:k:18'563=:=l0b<=;:398m72d290/=>;525d8j4532:10e?:m:18'563=:=l0b<=;:598m72f290/=>;525d8j4532<10e?:6:18'563=:=l0b<=;:798m72?290/=>;525d8j4532>10e<8m:18'563=9?k0b<=;:198m40>290/=>;517c8j4532810e<87:18'563=9?k0b<=;:398m400290/=>;517c8j4532:10e<89:18'563=9?k0b<=;:598m402290/=>;517c8j4532<10e<8;:18'563=9?k0b<=;:798m404290/=>;517c8j4532>10e<8=:18'563=9?k0b<=;:998m406290/=>;517c8j4532010e<9::18'563=9>>0b<=;:198m414290/=>;51668j4532810e<9=:18'563=9>>0b<=;:398m416290/=>;51668j4532:10e<9?:18'563=9>>0b<=;:598m40a290/=>;51668j4532<10e<8j:18'563=9>>0b<=;:798m40c290/=>;51668j4532>10e<8l:18'563=9>>0b<=;:998m4?5290/=>;51838j4532910e<7?:18'563=90;0b<=;:098m4>b290/=>;51838j4532;10e<6k:18'563=90;0b<=;:298m4>d290/=>;51838j4532=10e<6m:18'563=90;0b<=;:498m4>f290/=>;51838j4532?10e<66:18'563=90;0b<=;:698m4>?290/=>;51838j4532110e<68:18'563=90;0b<=;:898m4>1290/=>;51838j4532h10e<6::18'563=90;0b<=;:c98m4>4290/=>;51838j4532j10e<6=:18'563=90;0b<=;:e98m4>6290/=>;51838j4532l10e<6?:18'563=90;0b<=;:g98m41a290/=>;51838j45328:07d?8e;29 452283:7c?<4;32?>o6?m0;6)?<5;3:5>h6;=0:>65f16a94?"6;<0:5<5a126956=<a8=i6=4+12795<7<f89?6<:4;h34e?6=,89>6<7>;o300?7232c:544?:%301?7>92d:?94>6:9j5<>=83.:?84>909m562=9>10e<78:18'563=90;0b<=;:0:8?l7>>3:1(<=::0;2?k74<3;276g>9483>!74=3;2=6`>3582e>=n90>1<7*>3482=4=i9:>1=o54i0;0>5<#9:?1=4?4n017>4e<3`;3j7>5$016>4?63g;887?k;:k2<1<72-;897?61:l271<6m21b=:750;&270<6181e=>:51g98m4b1290/=>;51e78j4532910e<j;:18'563=9m?0b<=;:098m4b4290/=>;51e78j4532;10e<j=:18'563=9m?0b<=;:298m4b7290/=>;51e78j4532=10e<mi:18'563=9m?0b<=;:498m4eb290/=>;51e78j4532?10e<mk:18'563=9m?0b<=;:698m4ed290/=>;51e78j4532110e<mm:18'563=9m?0b<=;:898m4ef290/=>;51e78j4532h10e<m6:18'563=9m?0b<=;:c98m4e?290/=>;51e78j4532j10e<m8:18'563=9m?0b<=;:e98m4e2290/=>;51e78j4532l10e<m;:18'563=9m?0b<=;:g98m4e4290/=>;51e78j45328:07d?l2;29 45228n>7c?<4;32?>o6k80;6)?<5;3g1>h6;=0:>65f1b294?"6;<0:h85a126956=<a8hm6=4+12795a3<f89?6<:4;h3aa?6=,89>6<j:;o300?7232c:ni4?:%301?7c=2d:?94>6:9j5ge=83.:?84>d49m562=9>10e<ln:18'563=9m?0b<=;:0:8?l7e13:1(<=::0f6?k74<3;276g>b983>!74=3;o96`>3582e>=n9k=1<7*>3482`0=i9:>1=o54i0`5>5<#9:?1=i;4n017>4e<3`;i97>5$016>4b23g;887?k;:k2f1<72-;897?k5:l271<6m21b=o=50;&270<6l<1e=>:51g98m4d5290/=>;51e78j4532;:07d?m1;29 45228n>7c?<4;02?>o6io0;6)?<5;3g1>h6;=09>65f1`g94?"6;<0:h85a126966=<a8ko6=4+12795a3<f89?6?:4;h3bg?6=,89>6<j:;o300?4232c:mo4?:%301?7c=2d:?94=6:9j5dg=83.:?84>d49m562=:>10e<o6:18'563=9m?0b<=;:3:8?l7f03:1(<=::0f6?k74<38276g>a683>!74=3;o96`>3581e>=n9h<1<7*>3482`0=i9:>1>o54i0c7>5<#9:?1=i;4n017>7e<3`;j?7>5$016>4b23g;887<k;:k2e7<72-;897?k5:l271<5m21b=l?50;&270<6l<1e=>:52g98m4g7290/=>;51e78j4532::07d?6f;29 45228n>7c?<4;12?>o61l0;6)?<5;3g1>h6;=08>65f18f94?"6;<0:h85a126976=<a83h6=4+12795a3<f89?6>:4;h3:f?6=,89>6<j:;o300?5232c:hl4?:%301?7c=2d:?94<6:9j5a?=83.:?84>d49m562=;>10e<j7:18'563=9m?0b<=;:2:8?l7c?3:1(<=::0f6?k74<39276g>d083>!74=3;o96`>3580e>=n9j<1<7*>3482`0=i9:>1?o54i0`a>5<#9:?1=i;4n017>6e<3`;i<7>5$016>4b23g;887=k;:k2e0<72-;897?k5:l271<4m21b=4o50;&270<6l<1e=>:53g98f43f290:6=4?{%372?ba3A;>56F>489l``<722wi=9950;``>5<7s-;?:7?<6:J21<=O9=30V>85cz691?0=?3n1i7h5118:>d<6:3;86p`<e;31?k5a2;>0blj50:l`b?6<,mi1=9;4$ef9513<,8836<5+13;95>"b8380(h?52:&f6?4<,l91>6*j4;08 `3=:2.:9:4>549'514=92.n47<4$d;96>"bi380(hl52:&fg?4<,ln1>6*je;08 ``=:2.m<7<4$g396>"a:380(k=52:&e0?4<,o?1>6*i6;08 c1=:2.m47<4$g;96>"ai380(kl52:&eg?4<,on1>6*ie;08 c`=:2.:<=4=;%335?4<,8:96?5+11196>"68=097)??5;08 4612;1/==952:&24=<53-;;57<4$02b>7=#99h1>6*>0b81?!77l380(<>j:39'55`=:2.:==4=;%325?4<,8;96?5+10196>"69=097)?>5;08 4712;1/=<952:&25=<53-;:57<4$03b>7=#98h1>6*>1b81?!76l380(<?j:39'54`=:2.:>=4=;%315?4<,8896?5+13196>"6:=097)?=5;08 4412;1/=?952:&26d<6;81/=>l51568 45d2:=0(<=k:258 45b289:7)?<f;375>"b>380(h952:&213<6=<1/=9=51:k0=?6=3`9j6=44iec94?=nlk0;66g>3883>>o6;h0;66g>3683>>o6;10;66g>d;29 45228i0b<=;:198m4d=83.:?84>c:l271<632c:m7>5$016>4e<f89?6?54i0;94?"6;<0:o6`>3580?>o5>3:1(<=::0a8j4532=10e?;50;&270<6k2d:?94:;:k10?6=,89>6<m4n017>3=<a;91<7*>3482g>h6;=0<76g=2;29 45228i0b<=;:998m77=83.:?84>c:l271<>32c9<7>5$016>4e<f89?6l54i0d94?"6;<0:o6`>358a?>o6m3:1(<=::0a8j4532j10e<650;&270<6k2d:?94k;:k1g?6=,89>6?l4n017>5=<a;k1<7*>3481f>h6;=0:76g=9;29 4522;h0b<=;:398m7>=83.:?84=b:l271<432c897>5$016>7d<f89?6954i2694?"6;<09n6`>3586?>o4;3:1(<=::3`8j4532?10e><50;&270<5j2d:?948;:k05?6=,89>6?l4n017>==<a::1<7*>3481f>h6;=0276g=f;29 4522;h0b<=;:`98m7c=83.:?84=b:l271<e32c9h7>5$016>7d<f89?6n54i3594?"6;<09n6`>358g?>o213:1(<=::4:8j4532910e8950;&270<202d:?94>;:k61?6=,89>6864n017>7=<a<>1<7*>3486<>h6;=0876g:3;29 4522<20b<=;:598m04=83.:?84:8:l271<232c>=7>5$016>0><f89?6;54i4294?"6;<0>46`>3584?>o3n3:1(<=::4:8j4532110e9k50;&270<202d:?946;:k7`?6=,89>6864n017>d=<a=i1<7*>3486<>h6;=0i76g;a;29 4522<20b<=;:b98m1?=83.:?84:8:l271<c32c?47>5$016>0><f89?6h54i5594?"6;<0>46`>358e?>o3>3:1(<=::4:8j45328:07d:::18'563==11e=>:51098m12=83.:?84:8:l271<6:21b8>4?:%301?3?3g;887?<;:k76?6=,89>6864n017>42<3`>:6=4+12791==i9:>1=854i7294?"6;<0>46`>35822>=n=o0;6)?<5;7;?k74<3;<76g:e;29 4522<20b<=;:0:8?l3c290/=>;5599m562=9010e8m50;&270<202d:?94>a:9j1g<72-;897;7;o300?7e32c>m7>5$016>0><f89?6<m4;h75>5<#9:?1955a12695a=<a=h1<7*>3486<>h6;=0:i65f4183>!74=3?37c?<4;3e?>o0i3:1(<=::6;8j4532910e:650;&270<012d:?94>;:k42?6=,89>6:74n017>7=<a>?1<7*>3484=>h6;=0876g84;29 4522>30b<=;:598m25=83.:?8489:l271<232c<>7>5$016>2?<f89?6;54i6394?"6;<0<56`>3584?>o083:1(<=::6;8j4532110e;h50;&270<012d:?946;:k5a?6=,89>6:74n017>d=<a?n1<7*>3484=>h6;=0i76g9b;29 4522>30b<=;:b98m3g=83.:?8489:l271<c32c=57>5$016>2?<f89?6h54i7:94?"6;<0<56`>358e?>o1?3:1(<=::6;8j45328:07d89:18'563=?01e=>:51098m33=83.:?8489:l271<6:21b:94?:%301?1>3g;887?<;:k57?6=,89>6:74n017>42<3`<96=4+12793<=i9:>1=854i9394?"6;<0<56`>35822>=n090;6)?<5;5:?k74<3;<76g8f;29 4522>30b<=;:0:8?l1b290/=>;5789m562=9010e:j50;&270<012d:?94>a:9j3f<72-;89796;o300?7e32c<n7>5$016>2?<f89?6<m4;h54>5<#9:?1;45a12695a=<a?i1<7*>3484=>h6;=0:i65f6083>!74=3=27c?<4;3e?>o?>3:1(<=::978j4532910e5:50;&270<?=2d:?94>;:k;7?6=,89>65;4n017>7=<a181<7*>348;1>h6;=0876g7b;29 45221k0b<=;:198m=?=83.:?847a:l271<632c347>5$016>=g<f89?6?54i9594?"6;<03m6`>3580?>o6<o0;6)?<5;37a>h6;=0;76g>4e83>!74=3;?i6`>3582?>o6<j0;6)?<5;37a>h6;=0976g>4c83>!74=3;?i6`>3580?>o6==0;6)?<5;367>h6;=0;76g>5383>!74=3;>?6`>3582?>o6=80;6)?<5;367>h6;=0976g>5183>!74=3;>?6`>3580?>if=3:1(<=::`68j4532910cl=50;&270<f<2d:?94>;:mb5?6=,89>6l:4n017>7=<gh:1<7*>348b0>h6;=0876a6f;29 4522h>0b<=;:598k<c=83.:?84n4:l271<232e2h7>5$016>d2<f89?6;54o8a94?"6;<0j86`>3584?>i>j3:1(<=::`68j4532110c4o50;&270<f<2d:?946;:m:=?6=,89>6l:4n017>d=<g021<7*>348b0>h6;=0i76a66;29 4522h>0b<=;:b98k<3=83.:?84n4:l271<c32e287>5$016>d2<f89?6h54o8194?"6;<0j86`>358e?>i>:3:1(<=::`68j45328:07b7>:18'563=i=1e=>:51098k<6=83.:?84n4:l271<6:21d4k4?:%301?g33g;887?<;:m;a?6=,89>6l:4n017>42<3f2o6=4+1279e1=i9:>1=854o`a94?"6;<0j86`>35822>=hik0;6)?<5;c7?k74<3;<76ana;29 4522h>0b<=;:0:8?jg>290/=>;5a59m562=9010cl650;&270<f<2d:?94>a:9le2<72-;897o;;o300?7e32ej:7>5$016>d2<f89?6<m4;nc1>5<#9:?1m95a12695a=<g0=1<7*>348b0>h6;=0:i65`8b83>!74=3k?7c?<4;3e?>id?3:1(<=::b48j4532910cn;50;&270<d>2d:?94>;:m`7?6=,89>6n84n017>7=<gj81<7*>348`2>h6;=0876al1;29 4522j<0b<=;:598kf6=83.:?84l6:l271<232eij7>5$016>f0<f89?6;54ocg94?"6;<0h:6`>3584?>iel3:1(<=::b48j4532110com50;&270<d>2d:?946;:maf?6=,89>6n84n017>d=<gkk1<7*>348`2>h6;=0i76am8;29 4522j<0b<=;:b98kg1=83.:?84l6:l271<c32ei:7>5$016>f0<f89?6h54oc794?"6;<0h:6`>358e?>ie<3:1(<=::b48j45328:07bl<:18'563=k?1e=>:51098kg4=83.:?84l6:l271<6:21dn<4?:%301?e13g;887?<;:ma4?6=,89>6n84n017>42<3fkm6=4+1279g3=i9:>1=854obg94?"6;<0h:6`>35822>=hkm0;6)?<5;a5?k74<3;<76alc;29 4522j<0b<=;:0:8?jee290/=>;5c79m562=9010cno50;&270<d>2d:?94>a:9lg<<72-;897m9;o300?7e32eh47>5$016>f0<f89?6<m4;na7>5<#9:?1o;5a12695a=<gk31<7*>348`2>h6;=0:i65`ad83>!74=3i=7c?<4;3e?>ic<3:1(<=::e18j4532910ci<50;&270<c;2d:?94>;:mg5?6=,89>6i=4n017>7=<gm:1<7*>348g7>h6;=0876ak9;29 4522m20b<=;:198ka1=83.:?84k8:l271<632eo:7>5$016>a><f89?6?54oe794?"6;<0o46`>3580?>{e9=21<7ll:183!73>3;8:6F>589K51?<R:<1ov:55;493?b=m3l1==46:`826?742td8i7?=;o1e>72<fhn1<6`lf;28 ae=9=?0(ij51578 44?281/=?751:&f4?4<,l;1>6*j2;08 `5=:2.n87<4$d796>"6=>0:985+15095>"b0380(h752:&fe?4<,lh1>6*jc;08 `b=:2.ni7<4$dd96>"a8380(k?52:&e6?4<,o91>6*i4;08 c3=:2.m:7<4$g596>"a0380(k752:&ee?4<,oh1>6*ic;08 cb=:2.mi7<4$gd96>"689097)??1;08 4652;1/===52:&241<53-;;97<4$025>7=#99=1>6*>0981?!771380(<>n:39'55d=:2.:<n4=;%33`?4<,8:n6?5+11d96>"699097)?>1;08 4752;1/=<=52:&251<53-;:97<4$035>7=#98=1>6*>1981?!761380(<?n:39'54d=:2.:=n4=;%32`?4<,8;n6?5+10d96>"6:9097)?=1;08 4452;1/=?=52:&261<53-;997<4$005>7=#9;=1>6*>2`8274=#9:h1=9:4$01`>61<,89o6>94$01f>4563-;8j7?;1:&f2?4<,l=1>6*>578210=#9=91=6g<9;29?l5f2900eio50;9j`g<722c:?44?::k27d<722c:?:4?::k27=<722c:h7>5$016>4e<f89?6=54i0`94?"6;<0:o6`>3582?>o6i3:1(<=::0a8j4532;10e<750;&270<6k2d:?94<;:k12?6=,89>6<m4n017>1=<a;?1<7*>3482g>h6;=0>76g=4;29 45228i0b<=;:798m75=83.:?84>c:l271<032c9>7>5$016>4e<f89?6554i3394?"6;<0:o6`>358:?>o583:1(<=::0a8j4532h10e<h50;&270<6k2d:?94m;:k2a?6=,89>6<m4n017>f=<a821<7*>3482g>h6;=0o76g=c;29 4522;h0b<=;:198m7g=83.:?84=b:l271<632c957>5$016>7d<f89?6?54i3:94?"6;<09n6`>3580?>o4=3:1(<=::3`8j4532=10e>:50;&270<5j2d:?94:;:k07?6=,89>6?l4n017>3=<a:81<7*>3481f>h6;=0<76g<1;29 4522;h0b<=;:998m66=83.:?84=b:l271<>32c9j7>5$016>7d<f89?6l54i3g94?"6;<09n6`>358a?>o5l3:1(<=::3`8j4532j10e?950;&270<5j2d:?94k;:k6=?6=,89>6864n017>5=<a<=1<7*>3486<>h6;=0:76g:5;29 4522<20b<=;:398m02=83.:?84:8:l271<432c>?7>5$016>0><f89?6954i4094?"6;<0>46`>3586?>o293:1(<=::4:8j4532?10e8>50;&270<202d:?948;:k7b?6=,89>6864n017>==<a=o1<7*>3486<>h6;=0276g;d;29 4522<20b<=;:`98m1e=83.:?84:8:l271<e32c?m7>5$016>0><f89?6n54i5;94?"6;<0>46`>358g?>o303:1(<=::4:8j4532l10e9950;&270<202d:?94i;:k72?6=,89>6864n017>46<3`>>6=4+12791==i9:>1=<54i5694?"6;<0>46`>35826>=n<:0;6)?<5;7;?k74<3;876g;2;29 4522<20b<=;:068?l26290/=>;5599m562=9<10e;>50;&270<202d:?94>6:9j1c<72-;897;7;o300?7032c>i7>5$016>0><f89?6<64;h7g>5<#9:?1955a12695<=<a<i1<7*>3486<>h6;=0:m65f5c83>!74=3?37c?<4;3a?>o2i3:1(<=::4:8j45328i07d;9:18'563==11e=>:51e98m1d=83.:?84:8:l271<6m21b8=4?:%301?3?3g;887?i;:k4e?6=,89>6:74n017>5=<a>21<7*>3484=>h6;=0:76g86;29 4522>30b<=;:398m23=83.:?8489:l271<432c<87>5$016>2?<f89?6954i6194?"6;<0<56`>3586?>o0:3:1(<=::6;8j4532?10e:?50;&270<012d:?948;:k44?6=,89>6:74n017>==<a?l1<7*>3484=>h6;=0276g9e;29 4522>30b<=;:`98m3b=83.:?8489:l271<e32c=n7>5$016>2?<f89?6n54i7c94?"6;<0<56`>358g?>o113:1(<=::6;8j4532l10e;650;&270<012d:?94i;:k53?6=,89>6:74n017>46<3`<=6=4+12793<=i9:>1=<54i7794?"6;<0<56`>35826>=n>=0;6)?<5;5:?k74<3;876g93;29 4522>30b<=;:068?l05290/=>;5789m562=9<10e5?50;&270<012d:?94>6:9j<5<72-;89796;o300?7032c<j7>5$016>2?<f89?6<64;h5f>5<#9:?1;45a12695<=<a>n1<7*>3484=>h6;=0:m65f7b83>!74=3=27c?<4;3a?>o0j3:1(<=::6;8j45328i07d98:18'563=?01e=>:51e98m3e=83.:?8489:l271<6m21b:<4?:%301?1>3g;887?i;:k;2?6=,89>65;4n017>5=<a1>1<7*>348;1>h6;=0:76g73;29 45221?0b<=;:398m=4=83.:?8475:l271<432c3n7>5$016>=g<f89?6=54i9;94?"6;<03m6`>3582?>o?03:1(<=::9c8j4532;10e5950;&270<?i2d:?94<;:k20c<72-;897?;e:l271<732c:8i4?:%301?73m2d:?94>;:k20f<72-;897?;e:l271<532c:8o4?:%301?73m2d:?94<;:k211<72-;897?:3:l271<732c:9?4?:%301?72;2d:?94>;:k214<72-;897?:3:l271<532c:9=4?:%301?72;2d:?94<;:mb1?6=,89>6l:4n017>5=<gh91<7*>348b0>h6;=0:76an1;29 4522h>0b<=;:398kd6=83.:?84n4:l271<432e2j7>5$016>d2<f89?6954o8g94?"6;<0j86`>3586?>i>l3:1(<=::`68j4532?10c4m50;&270<f<2d:?948;:m:f?6=,89>6l:4n017>==<g0k1<7*>348b0>h6;=0276a69;29 4522h>0b<=;:`98k<>=83.:?84n4:l271<e32e2:7>5$016>d2<f89?6n54o8794?"6;<0j86`>358g?>i><3:1(<=::`68j4532l10c4=50;&270<f<2d:?94i;:m:6?6=,89>6l:4n017>46<3f3:6=4+1279e1=i9:>1=<54o8294?"6;<0j86`>35826>=h0o0;6)?<5;c7?k74<3;876a7e;29 4522h>0b<=;:068?j>c290/=>;5a59m562=9<10clm50;&270<f<2d:?94>6:9leg<72-;897o;;o300?7032ejm7>5$016>d2<f89?6<64;nc:>5<#9:?1m95a12695<=<gh21<7*>348b0>h6;=0:m65`a683>!74=3k?7c?<4;3a?>if>3:1(<=::`68j45328i07bo=:18'563=i=1e=>:51e98k<1=83.:?84n4:l271<6m21d4n4?:%301?g33g;887?i;:m`3?6=,89>6n84n017>5=<gj?1<7*>348`2>h6;=0:76al3;29 4522j<0b<=;:398kf4=83.:?84l6:l271<432eh=7>5$016>f0<f89?6954ob294?"6;<0h:6`>3586?>ien3:1(<=::b48j4532?10cok50;&270<d>2d:?948;:ma`?6=,89>6n84n017>==<gki1<7*>348`2>h6;=0276amb;29 4522j<0b<=;:`98kgg=83.:?84l6:l271<e32ei47>5$016>f0<f89?6n54oc594?"6;<0h:6`>358g?>ie>3:1(<=::b48j4532l10co;50;&270<d>2d:?94i;:ma0?6=,89>6n84n017>46<3fh86=4+1279g3=i9:>1=<54oc094?"6;<0h:6`>35826>=hj80;6)?<5;a5?k74<3;876am0;29 4522j<0b<=;:068?jga290/=>;5c79m562=9<10cnk50;&270<d>2d:?94>6:9lga<72-;897m9;o300?7032eho7>5$016>f0<f89?6<64;naa>5<#9:?1o;5a12695<=<gjk1<7*>348`2>h6;=0:m65`c883>!74=3i=7c?<4;3a?>id03:1(<=::b48j45328i07bm;:18'563=k?1e=>:51e98kg?=83.:?84l6:l271<6m21dmh4?:%301?e13g;887?i;:mg0?6=,89>6i=4n017>5=<gm81<7*>348g7>h6;=0:76ak1;29 4522m90b<=;:398ka6=83.:?84k3:l271<432eo57>5$016>a><f89?6=54oe594?"6;<0o46`>3582?>ic>3:1(<=::e:8j4532;10ci;50;&270<c02d:?94<;:p57`=83>iw0?:a;ff?873?3;8;63>46827==:9==1=>74=064>45f34;?;7<?;<373?7a34;?;7?j;<373?7?34;?;7=?;<373?4a34;?;7<j;<373?4c34;?;7<8;<373?3>34;?;7;8;<373?3234;?;7;;;<373?3434;?;7;=;<373?3634;?;7;?;<373?2a34;?;7:j;<373?2c34;?;7:l;<373?2f34;?;7:6;<373?2?34;?;7:8;<373?>134;?;76;;<373?>434;?;76=;<373?>e34;?;766;<373?>?34;?;768;<37<?74?27:854>399>51>=9:301<:7:01b?873038;70?;8;3e?87303;n70?;8;3;?873039;70?;8;0e?873038n70?;8;0g?873038<70?;8;7:?87303?<70?;8;76?87303??70?;8;70?87303?970?;8;72?87303?;70?;8;6e?87303>n70?;8;6g?87303>h70?;8;6b?87303>270?;8;6;?87303><70?;8;:5?873032?70?;8;:0?873032970?;8;:a?873032270?;8;:;?873032<7p}>6083>6}Y9?;01<:8:338942?2;;0q~?92;297~X6>;16=995239>51>=:;1v<8<:180[71;27:8:4=3:?20=<5;2wx=;:50;1xZ40334;?;7<;;<37<?433ty::84?:2y]533<58><6?;4=06;>73<uz;=:7>53z\223=:9==1>;5215:963=z{8<<6=4<{_353>;6<>0:563>4982=>{t9?21<7=t^04;?873?3;j70?;8;3b?xu6>00;6>uQ17;8942028h01<:7:0`8yv71j3:1?vP>6c9>511=9m16=9651e9~w40d2908wS?9c:?202<4927:854<1:p53b=839pR<8k;<373?5534;?47==;|q22`<72:qU=;k4=064>65<58>36>=4}r35b?6=;rT::k52155971=:9=21?95rs053>5<4sW;<<63>46801>;6<10896s|16394?5|V8=:70?;7;0;?87303837p}>7383>6}Y9>801<:8:3;8942?2;30q~?83;297~X6?:16=9952`9>51>=:h1v<9::180[70=27:8:4=c:?20=<5k2wx=:950;1xZ41034;?;7=6;<37<?5>3ty:;54?:2y]52><58><6>o4=06;>6g<uz;<57>52z\23<=:9==18=5rs05b>5<5sW;<m63>46875>{t9>h1<7<t^05a?873?3>97p}>7b83>7}Y9>i01<:8:518yv70l3:1>vP>7e9>511=<=1v<9j:181[70m27:8:4;5:p52`=838pR<9i;<373?213ty:4=4?:3y]5=6<58>369>4}r3;5?6=:rT:4<5215:90g=z{8296=4={_3;6>;6<10>:6s|19194?4|V82870?;8;7b?xu60=0;6?uQ196894202=h0q~?75;296~X60<16=9655c9~w4>12909wS?76:?20=<2k2wx=5950;0xZ4>034;?47;k;|q2<=<72;qU=564=06;>0c<uz;357>52z\2<<=:9=219k5rs0:b>5<5sW;3m63>49854>{t91h1<7<t^0:a?87303>:7p}>8b83>7}Y91i01<:7:508yv7?l3:1>vP>8e9>51>=<:1v<6j:181[7?m27:854;4:p5=`=838pR<6i;<373?313ty:5=4?:3y]5<6<58>369;4}r3:6?6=:rT:5?5215:903=z{8386=4={_3:7>;6<>0>m6s|18694?4|V83?70?;7;7a?xu61<0;6?uQ187894202<i0q~?66;296~X61?16=9955e9~w4?02909wS?67:?202<2m2wx=4650;0xZ4??34;?;7;i;|q2=<<72;qU=474=064>36<uz;2m7>52z\2=d=:9==1:<5rs0;a>5<5sW;2n63>46856>{t90i1<7<t^0;`?873?3<87p}>9e83>7}Y90n01<:8:768yv7>m3:1>vP>9d9>511=><1v<7i:181[7>n27:8:496:p5d6=838pR<o?;<373?003ty:m<4?:3y]5d7<58>36;?4}r3b6?6=:rT:m?5215:92f=z{8k86=4={_3b7>;6<10<;6s|1`694?4|V8k?70?;8;5a?xu6i<0;6?uQ1`7894202?i0q~?n6;296~X6i?16=9657b9~w4g02909wS?n7:?20=<0l2wx=l650;0xZ4g?34;?479j;|q2e<<72;qU=l74=06;>2`<uz;jm7>52z\2ed=:9=214=5rs0ca>5<5sW;jn63>498;5>{t9hi1<7<t^0c`?87303<97p}>ae83>7}Y9hn01<:7:718yv7fm3:1>vP>ad9>51>=>=1v<oi:181[7fn27:85495:p5g6=838pR<l?;<373?103ty:n<4?:3y]5g7<58>36;84}r3a6?6=:rT:n?5215:922=z{8h86=4={_3a7>;6<>0=46s|1c694?4|V8h?70?;7;4:?xu6j<0;6?uQ1c7894202?k0q~?m6;296~X6j?16=9956c9~w4d02909wS?m7:?202<1l2wx=o650;0xZ4d?34;?;78j;|q2f<<72;qU=o74=064>3`<uz;im7>52z\2fd=:9==1;=5rs0`a>5<5sW;in63>4684f>{t9ki1<7<t^0``?873?3=:7p}>be83>7}Y9kn01<:8:608yv7em3:1>vP>bd9>511=?:1v<li:181[7en27:8:484:p5f6=838pR<m?;<373?123ty:o<4?:3y]5f7<58><6:84}r3`6?6=:rT:o?5215593==z{8i86=4={_3`7>;6<>0<m6s|1b694?4|V8i?70?;8;4;?xu6k<0;6?uQ1b78942?2?30q~?l6;296~X6k?16=9957b9~w4e02909wS?l7:?20=<1i2wx=n650;0xZ4e?34;?478m;|q2g<<72;qU=n74=06;>3b<uz;hm7>52z\2gd=:9=21:h5rs0aa>5<5sW;hn63>4985b>{t9ji1<7<t^0a`?87303=;7p}>ce83>7}Y9jn01<:7:638yv7dm3:1>vP>cd9>51>=?;1v<mi:181[7dn27:85483:p5a6=838pR<j?;<37<?133ty:h<4?:3y]5a7<58><6:j4}r3g6?6=:rT:h?5215:930=z{8n86=4={_3g7>;6<10<:6s|1e694?4|V8n?70?;8;5;?xu6l?0;6?uQ1e48942?2>k0q~?k7;296~X6l>16=9957d9~w4b?2909wS?k8:?202<0n2wx=i750;0xZ4b>34;?;76?;|q2`d<72;qU=io4=064>=7<uz;on7>52z\2`g=:9==14n5rs0f`>5<5sW;oo63>468;`>{t9mn1<7<t^0fg?873?32n7p}>dd83>7}Y9mo01<:8:9d8yv7cn3:1>vP>dg9>511=191v<k?:181[7b827:8:461:p5`7=838pR<k>;<373??53ty:i?4?:3y]5`4<58>365m4}r3f7?6=:rT:i>5215:9=2=z{8o?6=4={_3f0>;6<10j>6s|1d794?4|V8o>70?;8;c5?xu6m?0;6?uQ1d48942020=0q~?j7;296~X6m>16=965a69~w4c?2909wS?j8:?20=<f02wx=h750;0xZ4c>34;?47o6;|q2ad<72;qU=ho4=06;>dg<uz;nn7>52z\2ag=:9=21mo5rs0g`>5<5sW;no63>498bg>{t9ln1<7<t^0gg?873032o7p}>ed83>7}Y9lo01<:7:9g8yv7bn3:1>vP>eg9>51>=0o1v<h?:181[7a827:85460:p5c7=838pR<h>;<373?g53ty:j?4?:3y]5c4<58>364?4}r3e0?6=:rT:j95215:9=7=z{8l>6=4={_3e1>;6<>0j:6s|1g494?4|V8l=70?;7;c4?xu6n>0;6?uQ1g5894202h20q~?i8;296~X6n116=995a89~w4`>2909wS?i9:?202<fi2wx=ko50;0xZ4`f34;?;7om;|q2bg<72;qU=kl4=064>de<uz;mo7>52z\2bf=:9==1mh5rs0dg>5<5sW;mh63>468bb>{t9oo1<7<t^0df?873?3h;7p}>fg83>7}Y9ol01<:8:c38yv4783:1>vP=019>511=j;1v?>>:181[47927:8:4m3:p654=838pR?>=;<373?d33ty9<>4?:3y]655<58>36lk4}r030?6=:rT9<95215:9f<=z{;:>6=4={_031>;6<10h86s|21494?4|V;:=70?;8;a;?xu58>0;6?uQ215894202k30q~<?8;296~X58116=965c89~w76>2909wS<?9:?20=<di2wx>=o50;0xZ76f34;?47mm;|q14g<72;qU>=l4=06;>fe<uz8;o7>52z\14f=:9=21oi5rs32g>5<5sW8;h63>498`a>{t:9o1<7<t^32f?87303km7p}=0g83>7}Y:9l01<:7:c28yv4683:1>vP=119>51>=j81v??>:181[46927:854m2:p644=838pR??=;<373?e33ty9=>4?:3y]645<58>36o=4}r020?6=:rT9=95215:9f1=z{;;>6=4={_021>;6<>0i96s|20494?4|V;;=70?;7;`5?xu59>0;6?uQ205894202k=0q~<>8;296~X59116=995b99~w77>2909wS<>9:?202<ei2wx><o50;0xZ77f34;?;7lm;|q15g<72;qU><l4=064>ge<uz8:o7>52z\15f=:9==1ni5rs33g>5<5sW8:h63>468`<>{t:8o1<7<t^33f?873?3hn7p}=1g83>7}Y:8l01<:8:cd8yv4583:1>vP=219>511=k91v?<>:181[45927:8:4l1:p674=838pR?<=;<373?e53ty9>>4?:3y]675<58><6n=4}r010?6=:rT9>9521559g0=z{;8>6=4={_011>;6<>0h;6s|23494?4|V;8=70?;8;`6?xu5:>0;6?uQ2358942?2k<0q~<=8;296~X5:116=995c89~w74>2909wS<=9:?20=<e?2wx>?o50;0xZ74f34;?47l7;|q16g<72;qU>?l4=06;>gg<uz89o7>52z\16f=:9=21no5rs30g>5<5sW89h63>498ag>{t:;o1<7<t^30f?87303ho7p}=2g83>7}Y:;l01<:7:cg8yv4483:1>vP=319>51>=jo1v?=>:181[44927:854l0:p664=838pR?==;<37<?e63ty9?>4?:3y]665<58><6no4}r000?6=:rT9?95215:9g7=z{;9>6=4={_001>;6<10h?6s|22494?4|V;9=70?;8;a6?xu5;10;6?uQ22:8942?2j=0q~<<9;296~X5;016=995cc9~w75f2909wS<<a:?202<dk2wx>>l50;0xZ75e34;?;7mk;|q17f<72;qU>>m4=064>fc<uz88h7>53z\17a=:9==1hl5215:9`d=z{;9n6=4<{_00a>;6<>0on63>498gf>{t:=91<7=t^360?873?3;?h63>46820g=z{;>?6=4<{_070>;6<>0:8k52155951e<uz8?97>53z\100=:9=21=9j4=06;>42e3ty98:4?:2y]611<58>36<:i;<37<?73k2wx>9650;0xZ72?34;?;7?:0:p61?=838pR?:6;<373?7292wx>9o50;0xZ72f34;?47?:0:p61d=838pR?:m;<37<?7292wx>9m50;0xZ72d34;?;7?:2:p61b=838pR?:k;<373?72<2wx>9k50;0xZ72b34;?47?:2:p606=838pR?;?;<37<?72<2wvb?8n:182M7312we>;l50;3xL42>3td9:n4?:0yK51?<ug8=h7>51zJ20<=zf;<n6=4>{I37=>{i:?l1<7?tH06:?xh5?90;6<uG15;8yk4093:1=vF>489~j715290:wE?;9:m625=83;pD<:6;|l131<728qC=974}o041?6=9rB:845rn355>5<6sA;?56sa26594?7|@8>27p`=7983>4}O9=30qc<89;295~N6<01vb?9n:182M7312we>:l50;3xL42>3td9;n4?:0yK51?<ug8<h7>51zJ20<=zf;=n6=4>{I37=>{i:>l1<7?tH06:?xh5090;6<uG15;8yk4?93:1=vF>489~j7>5290:wE?;9:m6=5=83;pD<:6;|l1<1<728qC=974}o0;1?6=9rB:845rn3:5>5<6sA;?56sa29594?7|@8>27p`=8983>4}O9=30qc<79;295~N6<01vb?6n:182M7312we>5l50;3xL42>3td94n4?:0yK51?<ug83h7>51zJ20<=zf;2n6=4>{I37=>{i:1l1<7?tH06:?xh5190;6<uG15;8yk4>93:1=vF>489~j7?5290:wE?;9:m6<5=83;pD<:6;|l1=1<728qC=974}o0:1?6=9rB:845rn3;5>5<6sA;?56sa28594?7|@8>27p`=9983>4}O9=30qc<69;295~N6<01vb?7n:182M7312we>4l50;3xL42>3td95n4?:0yK51?<ug82h7>51zJ20<=zf;3n6=4>{I37=>{i:0l1<7?tH06:?xh5i90;6<uG15;8yk4f93:1=vF>489~j7g5290:wE?;9:m6d5=83;pD<:6;|l1e1<728qC=974}o0b1?6=9rB:845rn3c5>5<6sA;?56sa2`594?7|@8>27p`=a983>4}O9=30qc<n9;295~N6<01vb?on:182M7312we>ll50;3xL42>3td9mn4?:0yK51?<ug8jh7>51zJ20<=zf;kn6=4>{I37=>{i:hl1<7?tH06:?xh5j90;6<uG15;8yk4e93:1=vF>489~j7d5290:wE?;9:m6g5=83;pD<:6;|l1f1<728qC=974}o0a1?6=9rB:845rn3`5>5<6sA;?56sa2c594?7|@8>27p`=b983>4}O9=30qc<m9;295~N6<01vb?ln:182M7312we>ol50;3xL42>3td9nn4?:0yK51?<ug8ih7>51zJ20<=zf;hn6=4>{I37=>{i:kl1<7?tH06:?xh5k90;6<uG15;8yk4d93:1=vF>489~j7e5290:wE?;9:m6f5=83;pD<:6;|l1g1<728qC=974}o0`1?6=9rB:845rn3a5>5<6sA;?56sa2b594?7|@8>27p`=c983>4}O9=30qc<l9;295~N6<01vb?mn:182M7312we>nl50;3xL42>3td9on4?:0yK51?<ug8hh7>51zJ20<=zf;in6=4>{I37=>{i:jl1<7?tH06:?xh5l90;6<uG15;8yk4c93:1=vF>489~j7b5290:wE?;9:m6a5=83;pD<:6;|l1`1<728qC=974}o0g1?6=9rB:845rn3f5>5<6sA;?56sa2e594?7|@8>27p`=d983>4}O9=30qc<k9;295~N6<01vb?jn:182M7312we>il50;3xL42>3td9hn4?:0yK51?<ug8oh7>51zJ20<=zf;nn6=4>{I37=>{i:ml1<7?tH06:?xh5m90;6<uG15;8yk4b93:1=vF>489~j7c5290:wE?;9:m6`5=83;pD<:6;|l1a1<728qC=974}o0f1?6=9rB:845rn3g5>5<6sA;?56sa2d594?7|@8>27p`=e983>4}O9=30qc<j9;295~N6<01vb?kn:182M7312we>hl50;3xL42>3td9in4?:0yK51?<ug8nh7>51zJ20<=zf;on6=4>{I37=>{i:ll1<7?tH06:?xh5n90;6<uG15;8yk4a93:1=vF>489~j7`5290:wE?;9:m6c5=83;pD<:6;|l1b1<728qC=974}o0e1?6=9rB:845rn3d5>5<6sA;?56sa2g594?7|@8>27p`=f983>4}O9=30qc<i9;295~N6<01vb?hn:182M7312we>kl50;3xL42>3td9jn4?:0yK51?<ug8mh7>51zJ20<=zf;ln6=4>{I37=>{i:ol1<7?tH06:?xh4890;6<uG15;8yk5793:1=vF>489~j665290:wE?;9:m755=83;pD<:6;|l041<728qC=974}o131?6=9rB:845rn225>5<6sA;?56sa31594?7|@8>27p`<0983>4}O9=30qc=?9;295~N6<01vb>>n:182M7312we?=l50;3xL42>3td8<n4?:0yK51?<ug9;h7>51zJ20<=zf::n6=4>{I37=>{i;9l1<7?tH06:?xh4990;6<uG15;8yk5693:1=vF>489~j675290:wE?;9:m745=83;pD<:6;|l051<728qC=974}o121?6=9rB:845rn235>5<6sA;?56sa30594?7|@8>27p`<1983>4}O9=30qc=>9;295~N6<01vb>?n:182M7312we?<l50;3xL42>3td8=n4?:0yK51?<ug9:h7>51zJ20<=zf:;n6=4>{I37=>{i;8l1<7?tH06:?xh4:90;6<uG15;8yk5593:1=vF>489~j645290:wE?;9:m775=83;pD<:6;|l061<728qC=974}o111?6=9rB:845rn205>5<6sA;?56sa33594?7|@8>27p`<2983>4}O9=30qc==9;295~N6<01vb><n:182M7312we??l50;3xL42>3td8>n4?:0yK51?<ug99h7>51zJ20<=zf:8n6=4>{I37=>{i;;l1<7?tH06:?xh4;90;6<uG15;8yk5493:1=vF>489~j655290:wE?;9:m765=83;pD<:6;|l071<728qC=974}o101?6=9rB:845rn215>5<6sA;?56sa32594?7|@8>27p`<3983>4}O9=30qc=<9;295~N6<01vb>=n:182M7312we?>l50;3xL42>3td8?n4?:0yK51?<ug98h7>51zJ20<=zf:9n6=4>{I37=>{i;:l1<7?tH06:?xh4<90;6<uG15;8yk5393:1=vF>489~j625290:wE?;9:m715=83;pD<:6;|l001<728qC=974}o171?6=9rB:845rn265>5<6sA;?56sa35594?7|@8>27p`<4983>4}O9=30qc=;9;295~N6<01vb>:n:182M7312we?9l50;3xL42>3td88n4?:0yK51?<ug9?h7>51zJ20<=zutwKLNu;338`=64?8m;vLMLt0|BCT~{GH |
/s3adsp1800/sim/run/Makefile
0,0 → 1,3
include ../bin/Makefile |
/s3adsp1800/sim/bin/Makefile
0,0 → 1,83
###################################################################### |
#### #### |
#### ORPSoCv2 Xilinx simulation Makefile #### |
#### #### |
#### Description #### |
#### ORPSoCv2 Testbenches Makefile, containing rules for #### |
#### configuring and running different tests on the current #### |
#### ORPSoC(v2) design. #### |
#### #### |
#### To do: #### |
#### #### |
#### Author(s): #### |
#### - Julius Baxter, julius@opencores.org #### |
#### #### |
#### #### |
###################################################################### |
#### #### |
#### Copyright (C) 2009,2010,2011 Authors and 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 #### |
#### #### |
###################################################################### |
|
# Name of the directory we're currently in |
CUR_DIR=$(shell pwd) |
|
BOARD_ROOT=$(CUR_DIR)/../.. |
include $(BOARD_ROOT)/Makefile.inc |
|
# Simulation-specific paths and files from this one |
include $(PROJECT_ROOT)/scripts/make/Makefile-board-benchsrc.inc |
|
TEST ?= or1200-simple |
TESTS ?= or1200-simple or1200-cbasic or1200-dctest or1200-float or1200-mmu or1200-basic or1200-except or1200-tick or1200-ticksyscall uart-simple |
|
include $(PROJECT_ROOT)/scripts/make/Makefile-simulators.inc |
|
# Gets turned into verilog `define |
SIM_TYPE=RTL |
|
SIMULATOR ?= $(MODELSIM) |
|
# Include the test-defines.v generation rule |
include $(PROJECT_ROOT)/scripts/make/Makefile-sim-definesgen.inc |
|
# |
# Modelsim make rules for RTL tests |
# |
include $(PROJECT_ROOT)/scripts/make/Makefile-board-modelsim.inc |
|
# |
# RTL test rules |
# |
include $(PROJECT_ROOT)/scripts/make/Makefile-rtltestrules.inc |
|
# |
# Software make rules (called recursively) |
# |
include $(PROJECT_ROOT)/scripts/make/Makefile-board-sw.inc |
|
# |
# Cleaning rules |
# |
include $(PROJECT_ROOT)/scripts/make/Makefile-board-simclean.inc |
/s3adsp1800/sw/bootrom/bootrom.v
0,0 → 1,5
0 : wb_dat_o <= 32'h18000000; |
1 : wb_dat_o <= 32'h18800000; |
2 : wb_dat_o <= 32'ha8840100; |
3 : wb_dat_o <= 32'h44002000; |
4 : wb_dat_o <= 32'h15000000; |
/s3adsp1800/sw/bootrom/Makefile
0,0 → 1,27
# Makefile for bootROM Verilog |
# We will do it by building the main one, and applying our local board's |
# settings. |
# To rebuild after board.h is changed, a clean must be done first. |
|
# Set the path to our board's root directory |
BOARD_SW_ROOT=.. |
|
include $(BOARD_SW_ROOT)/Makefile.inc |
|
all: bootrom.v |
|
# Copy the one build in the root software path to here. |
bootrom.v: $(SW_ROOT)/bootrom/bootrom.v |
$(Q)cp -v $< . |
|
# Export BOARD so the Make script in the root software path knows we're to |
# use our board.h file, not theirs. |
export BOARD |
|
$(SW_ROOT)/bootrom/bootrom.v: |
$(Q)$(MAKE) -C $(SW_ROOT)/bootrom bootrom.v |
|
clean: |
$(Q)rm -f *.o *.bin *.hex *.in *.dis *.v |
$(Q)$(MAKE) -C $(SW_ROOT)/bootrom clean |
|
/s3adsp1800/sw/tests/ddr2cache/sim/ddr2cache-2.S
0,0 → 1,170
/* |
Simple test to exercise cache writeback |
|
Fills all of cache, then reads data back. |
|
Julius Baxter, ORSoC AB, <julius.baxter@orsoc.se> |
|
*/ |
#include "spr-defs.h" |
|
#define NUM_LINES 4 |
#define BYTES_PER_LINE 32 |
#define WORDS_PER_LINE 8 |
|
.section .vectors, "ax" |
|
/* ---[ 0x100: RESET exception ]----------------------------------------- */ |
.org 0x100 |
l.movhi r0, 0 |
/* Clear status register */ |
l.ori r1, r0, SPR_SR_SM |
l.mtspr r0, r1, SPR_SR |
/* Clear timer */ |
l.mtspr r0, r0, SPR_TTMR |
|
/* Jump to program initialisation code */ |
.global _start |
l.movhi r4, hi(_start) |
l.ori r4, r4, lo(_start) |
l.jr r4 |
l.nop |
|
|
/* =================================================== [ text ] === */ |
.section .text |
|
/* =================================================== [ start ] === */ |
|
.global _start |
|
_start: |
l.movhi r1,hi(_stack) |
l.ori r1,r1,lo(_stack) |
l.addi r2, r0, -3 |
l.and r1, r1, r2 |
|
l.movhi r2,0 /*r2 is line counter */ |
|
/* Write data into addresses that should step through the |
lines of the cache */ |
|
l.addi r5,r0,-(BYTES_PER_LINE-1) |
l.and r4,r1,r5 /* r4 has base address of place to access */ |
l.addi r4,r4,BYTES_PER_LINE /* Go to safe address, past top of stack */ |
|
/* report this address */ |
l.ori r3,r4,0 |
l.nop 0x2 |
|
wr_loop: |
l.muli r5,r2,BYTES_PER_LINE /* offset from base address */ |
l.add r6,r5,r4 /* Address to write to (line offset + base) */ |
|
/* report this address */ |
l.ori r3,r6,0 |
l.nop 0x2 |
|
/* report counter */ |
l.ori r3,r2,0 |
l.nop 0x2 |
|
/* r8 used as counter for words on line - do 128/4 = 32 writes */ |
l.movhi r8,0 |
|
wr_words_loop: |
/* r9 is data - top 16-bits is line number, bottom 16 is word */ |
l.slli r9,r2,16 |
l.or r9,r9,r8 |
|
/* report value we're writing */ |
l.ori r3,r9,0 |
l.nop 0x2 |
|
/* report address where writing */ |
l.ori r3,r6,0 |
l.nop 0x2 |
|
/* do memory access */ |
l.sw 0(r6),r9 /* Write counter to this address */ |
|
l.addi r6,r6,4 /* Increment memory pointer */ |
|
l.sfnei r8,WORDS_PER_LINE-1 /* Finished filling this line? */ |
l.bf wr_words_loop |
l.addi r8,r8,1 /* Increment word counter */ |
|
/* end of word write loop */ |
|
l.sfeqi r2,NUM_LINES-1 /* Done all lines? */ |
l.bnf wr_loop |
l.addi r2,r2,1 /* increment line counter */ |
|
/* end of line write loop */ |
|
/* reset line counter */ |
l.movhi r2,0 |
|
rd_loop: |
l.muli r5,r2,BYTES_PER_LINE /* offset from base address */ |
l.add r6,r5,r4 /* Address to write to (line offset + base) */ |
|
/* report this address */ |
l.ori r3,r6,0 |
l.nop 0x2 |
|
/* report counter */ |
l.ori r3,r2,0 |
l.nop 0x2 |
|
/* r8 used as counter for words on line - do 128/4 = 32 reads */ |
l.movhi r8,0 |
|
rd_words_loop: |
/* r9 is data - top 16-bits is line number, bottom 16 is word */ |
l.slli r9,r2,16 |
l.or r9,r9,r8 |
|
/* report address where reading */ |
l.ori r3,r6,0 |
l.nop 0x2 |
|
/* do memory access */ |
l.lwz r10, 0(r6) /* Read data */ |
|
/* report what we *should* read */ |
l.ori r3,r9,0 |
l.nop 0x2 |
|
/* report what we read */ |
l.ori r3,r10,0 |
l.nop 0x2 |
|
l.sfne r9,r10 /* Does data equal what it should? */ |
l.bf fail |
|
l.addi r6,r6,4 /* Increment memory pointer */ |
|
l.sfnei r8,WORDS_PER_LINE-1 /* Finished reading this line? */ |
l.bf rd_words_loop |
l.addi r8,r8,1 /* Increment word counter */ |
|
/* end of word read loop */ |
|
l.sfeqi r2,NUM_LINES-1 /* Done all lines? */ |
l.bnf rd_loop |
l.addi r2,r2,1 /* increment line counter */ |
|
/* end of read loop */ |
pass: |
l.movhi r3,0x8000 |
l.ori r3,r3,0x000d |
l.nop 0x2 |
l.movhi r3,0 |
l.nop 0x1 |
|
fail: |
l.movhi r3,0xbaaa |
l.ori r3,r3,0xaaad |
l.nop 0x1 |
|
/s3adsp1800/sw/tests/ddr2cache/sim/Makefile
0,0 → 1,14
# Set the path to our board's root directory |
BOARD_SW_ROOT=../../.. |
|
include $(BOARD_SW_ROOT)/Makefile.inc |
|
%.dis: %.elf |
$(Q)$(OR32_OBJDUMP) -d $< > $@ |
|
%.bin: %.elf |
$(Q)$(OR32_OBJCOPY) -O binary $< $@ |
|
clean: |
$(Q)rm -f *.elf *.bin *.vmem *.flashin *.dis |
|
/s3adsp1800/sw/tests/ddr2cache/sim/ddr2cache-1.S
0,0 → 1,119
/* |
Simple test to exercise cache writeback |
|
Hardcoded for cache with 4 lines of 32 bytes. |
|
Julius Baxter, ORSoC AB, <julius.baxter@orsoc.se> |
|
*/ |
#include "spr-defs.h" |
|
#define NUM_LINES 4 |
#define BYTES_PER_LINE 32 |
|
.section .vectors, "ax" |
|
/* ---[ 0x100: RESET exception ]----------------------------------------- */ |
.org 0x100 |
l.movhi r0, 0 |
/* Clear status register */ |
l.ori r1, r0, SPR_SR_SM |
l.mtspr r0, r1, SPR_SR |
/* Clear timer */ |
l.mtspr r0, r0, SPR_TTMR |
|
/* Jump to program initialisation code */ |
.global _start |
l.movhi r4, hi(_start) |
l.ori r4, r4, lo(_start) |
l.jr r4 |
l.nop |
|
|
/* =================================================== [ text ] === */ |
.section .text |
|
/* =================================================== [ start ] === */ |
|
.global _start |
|
_start: |
l.movhi r1,hi(_stack) |
l.ori r1,r1,lo(_stack) |
l.addi r2, r0, -3 |
l.and r1, r1, r2 |
|
l.movhi r2,0 /*r2 is counter */ |
|
/* Write data into addresses that should step through the |
lines of the cache */ |
|
l.addi r5,r0,-(BYTES_PER_LINE-1) |
l.and r4,r1,r5 /* r4 has base address of place to access */ |
l.addi r4,r4,BYTES_PER_LINE /* Go to safe address, past top of stack */ |
|
/* report this address */ |
l.ori r3,r4,0 |
l.nop 0x2 |
|
wr_loop: |
l.muli r5,r2,BYTES_PER_LINE /* offset from base address */ |
l.add r6,r5,r4 /* Address to write to (line offset + base) */ |
|
/* report this address */ |
l.ori r3,r6,0 |
l.nop 0x2 |
|
/* report counter */ |
l.ori r3,r2,0 |
l.nop 0x2 |
|
/* do memory access */ |
l.sw 0(r6),r2 /* Write counter to this address */ |
|
l.sfeqi r2,(NUM_LINES-1) /* Done all lines? */ |
l.bnf wr_loop |
l.addi r2,r2,1 /* increment line counter */ |
|
/* end of write loop */ |
|
/* reset counter */ |
l.movhi r2,0 |
|
rd_loop: |
l.muli r5,r2,BYTES_PER_LINE /* offset from base address */ |
l.add r6,r5,r4 /* Address to write to (line offset + base) */ |
|
/* report this address */ |
l.ori r3,r6,0 |
l.nop 0x2 |
|
/* report counter */ |
l.ori r3,r2,0 |
l.nop 0x2 |
|
/* do memory access */ |
l.lwz r7,0(r6) /* load value */ |
|
/* should equal r2 */ |
l.sfne r2,r7 |
l.bf fail |
l.nop |
|
l.sfeqi r2,(NUM_LINES-1) /* Done all lines? */ |
l.bnf rd_loop |
l.addi r2,r2,1 /* increment line counter */ |
|
/* end of read loop */ |
pass: |
l.movhi r3,0x8000 |
l.ori r3,r3,0x000d |
l.nop 0x2 |
l.movhi r3,0 |
l.nop 0x1 |
|
fail: |
l.movhi r3,0xbaaa |
l.ori r3,r3,0xaaad |
l.nop 0x1 |
|
/s3adsp1800/sw/tests/ethmac/sim/ethmac-rxtxcallresponse.c
0,0 → 1,681
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Interrupt-driven Ethernet MAC transmit test code //// |
//// //// |
//// Description //// |
//// Send packets while receiving packets //// |
//// //// |
//// Test data comes from pre-calculated array of random values, //// |
//// MAC TX buffer pointers are set to addresses in this array, //// |
//// saving copying the data around before transfers. //// |
//// //// |
//// Author(s): //// |
//// - jb, jb@orsoc.se, with parts taken from Linux kernel //// |
//// open_eth driver. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009 Authors and 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
#include "cpu-utils.h" |
#include "board.h" |
#include "int.h" |
#include "ethmac.h" |
#include "eth-phy-mii.h" |
|
volatile unsigned tx_done; |
volatile unsigned rx_done; |
static int next_tx_buf_num; |
|
/* Functions in this file */ |
void ethmac_setup(void); |
/* Interrupt functions */ |
void oeth_interrupt(void); |
static void oeth_rx(void); |
static void oeth_tx(void); |
|
/* Let the ethernet packets use a space beginning here for buffering */ |
#define ETH_BUFF_BASE 0x01000000 |
|
|
#define RXBUFF_PREALLOC 1 |
#define TXBUFF_PREALLOC 1 |
//#undef RXBUFF_PREALLOC |
//#undef TXBUFF_PREALLOC |
|
/* The transmitter timeout |
*/ |
#define TX_TIMEOUT (2*HZ) |
|
/* Buffer number (must be 2^n) |
*/ |
#define OETH_RXBD_NUM 16 |
#define OETH_TXBD_NUM 16 |
#define OETH_RXBD_NUM_MASK (OETH_RXBD_NUM-1) |
#define OETH_TXBD_NUM_MASK (OETH_TXBD_NUM-1) |
|
/* Buffer size |
*/ |
#define OETH_RX_BUFF_SIZE 0x600-4 |
#define OETH_TX_BUFF_SIZE 0x600-4 |
|
/* Buffer size (if not XXBUF_PREALLOC |
*/ |
#define MAX_FRAME_SIZE 1518 |
|
/* The buffer descriptors track the ring buffers. |
*/ |
struct oeth_private { |
//struct sk_buff* rx_skbuff[OETH_RXBD_NUM]; |
//struct sk_buff* tx_skbuff[OETH_TXBD_NUM]; |
|
unsigned short tx_next; /* Next buffer to be sent */ |
unsigned short tx_last; /* Next buffer to be checked if packet sent */ |
unsigned short tx_full; /* Buffer ring fuul indicator */ |
unsigned short rx_cur; /* Next buffer to be checked if packet |
received */ |
|
oeth_regs *regs; /* Address of controller registers. */ |
oeth_bd *rx_bd_base; /* Address of Rx BDs. */ |
oeth_bd *tx_bd_base; /* Address of Tx BDs. */ |
|
// struct net_device_stats stats; |
}; |
|
#define PHYNUM 7 |
|
// Data array of data to transmit, tx_data_array[] |
//#include "eth-rxtx-data.h" // Not used |
int tx_data_pointer; |
|
|
void |
eth_mii_write(char phynum, short regnum, short data) |
{ |
static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE); |
regs->miiaddress = (regnum << 8) | phynum; |
regs->miitx_data = data; |
regs->miicommand = OETH_MIICOMMAND_WCTRLDATA; |
regs->miicommand = 0; |
while(regs->miistatus & OETH_MIISTATUS_BUSY); |
} |
|
short |
eth_mii_read(char phynum, short regnum) |
{ |
static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE); |
regs->miiaddress = (regnum << 8) | phynum; |
regs->miicommand = OETH_MIICOMMAND_RSTAT; |
regs->miicommand = 0; |
while(regs->miistatus & OETH_MIISTATUS_BUSY); |
|
return regs->miirx_data; |
} |
|
|
|
// Wait here until all packets have been transmitted |
void |
wait_until_all_tx_clear(void) |
{ |
int i; |
volatile oeth_bd *tx_bd; |
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/ |
|
int some_tx_waiting = 1; |
|
while (some_tx_waiting) |
{ |
some_tx_waiting = 0; |
/* Go through the TX buffs, search for unused one */ |
for(i = 0; i < OETH_TXBD_NUM; i++) { |
|
// Looking for buffer ready for transmit |
if((tx_bd[i].len_status & OETH_TX_BD_READY)) |
some_tx_waiting = 1; |
|
} |
} |
} |
|
|
void |
ethphy_set_10mbit(int phynum) |
{ |
wait_until_all_tx_clear(); |
// Hardset PHY to just use 10Mbit mode |
short cr = eth_mii_read(phynum, MII_BMCR); |
cr &= ~BMCR_ANENABLE; // Clear auto negotiate bit |
cr &= ~BMCR_SPEED100; // Clear fast eth. bit |
eth_mii_write(phynum, MII_BMCR, cr); |
} |
|
|
void |
ethphy_set_100mbit(int phynum) |
{ |
wait_until_all_tx_clear(); |
// Hardset PHY to just use 100Mbit mode |
short cr = eth_mii_read(phynum, MII_BMCR); |
cr |= BMCR_ANENABLE; // Clear auto negotiate bit |
cr |= BMCR_SPEED100; // Clear fast eth. bit |
eth_mii_write(phynum, MII_BMCR, cr); |
} |
|
|
void |
ethmac_setup(void) |
{ |
// from arch/or32/drivers/open_eth.c |
volatile oeth_regs *regs; |
|
regs = (oeth_regs *)(OETH_REG_BASE); |
|
/* Reset MII mode module */ |
regs->miimoder = OETH_MIIMODER_RST; /* MII Reset ON */ |
regs->miimoder &= ~OETH_MIIMODER_RST; /* MII Reset OFF */ |
regs->miimoder = 0x64; /* Clock divider for MII Management interface */ |
|
/* Reset the controller. |
*/ |
regs->moder = OETH_MODER_RST; /* Reset ON */ |
regs->moder &= ~OETH_MODER_RST; /* Reset OFF */ |
|
/* Setting TXBD base to OETH_TXBD_NUM. |
*/ |
regs->tx_bd_num = OETH_TXBD_NUM; |
|
|
/* Set min/max packet length |
*/ |
regs->packet_len = 0x00400600; |
|
/* Set IPGT register to recomended value |
*/ |
regs->ipgt = 0x12; |
|
/* Set IPGR1 register to recomended value |
*/ |
regs->ipgr1 = 0x0000000c; |
|
/* Set IPGR2 register to recomended value |
*/ |
regs->ipgr2 = 0x00000012; |
|
/* Set COLLCONF register to recomended value |
*/ |
regs->collconf = 0x000f003f; |
|
/* Set control module mode |
*/ |
#if 0 |
regs->ctrlmoder = OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW; |
#else |
regs->ctrlmoder = 0; |
#endif |
|
/* Clear MIIM registers */ |
regs->miitx_data = 0; |
regs->miiaddress = 0; |
regs->miicommand = 0; |
|
regs->mac_addr1 = ETH_MACADDR0 << 8 | ETH_MACADDR1; |
regs->mac_addr0 = ETH_MACADDR2 << 24 | ETH_MACADDR3 << 16 | ETH_MACADDR4 << 8 | ETH_MACADDR5; |
|
/* Clear all pending interrupts |
*/ |
regs->int_src = 0xffffffff; |
|
/* Promisc, IFG, CRCEn |
*/ |
regs->moder |= OETH_MODER_PRO | OETH_MODER_PAD | OETH_MODER_IFG | OETH_MODER_CRCEN | OETH_MODER_FULLD; |
|
/* Enable interrupt sources. |
*/ |
|
regs->int_mask = OETH_INT_MASK_TXB | |
OETH_INT_MASK_TXE | |
OETH_INT_MASK_RXF | |
OETH_INT_MASK_RXE | |
OETH_INT_MASK_BUSY | |
OETH_INT_MASK_TXC | |
OETH_INT_MASK_RXC; |
|
// Buffer setup stuff |
volatile oeth_bd *tx_bd, *rx_bd; |
int i,j,k; |
|
/* Initialize TXBD pointer |
*/ |
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; |
|
/* Initialize RXBD pointer |
*/ |
rx_bd = ((volatile oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM; |
|
/* Preallocated ethernet buffer setup */ |
unsigned long mem_addr = ETH_BUFF_BASE; /* Defined at top */ |
|
// Setup TX Buffers |
for(i = 0; i < OETH_TXBD_NUM; i++) { |
//tx_bd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC | OETH_RX_BD_IRQ; |
tx_bd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC; |
tx_bd[i].addr = mem_addr; |
mem_addr += OETH_TX_BUFF_SIZE; |
} |
tx_bd[OETH_TXBD_NUM - 1].len_status |= OETH_TX_BD_WRAP; |
|
// Setup RX buffers |
for(i = 0; i < OETH_RXBD_NUM; i++) { |
rx_bd[i].len_status = OETH_RX_BD_EMPTY | OETH_RX_BD_IRQ; // Init. with IRQ |
rx_bd[i].addr = mem_addr; |
mem_addr += OETH_RX_BUFF_SIZE; |
} |
rx_bd[OETH_RXBD_NUM - 1].len_status |= OETH_RX_BD_WRAP; // Last buffer wraps |
|
/* Enable RX and TX in MAC |
*/ |
regs->moder &= ~(OETH_MODER_RXEN | OETH_MODER_TXEN); |
regs->moder |= OETH_MODER_RXEN | OETH_MODER_TXEN; |
|
next_tx_buf_num = 0; // init tx buffer pointer |
|
return; |
} |
|
// Enable RX in ethernet MAC |
void |
oeth_enable_rx(void) |
{ |
volatile oeth_regs *regs; |
regs = (oeth_regs *)(OETH_REG_BASE); |
regs->moder |= OETH_MODER_RXEN; |
} |
|
// Disable RX in ethernet MAC |
void |
oeth_disable_rx(void) |
{ |
volatile oeth_regs *regs; |
regs = (oeth_regs *)(OETH_REG_BASE); |
regs->moder &= ~(OETH_MODER_RXEN); |
} |
|
|
/* Setup buffer descriptors with data */ |
/* length is in BYTES */ |
void tx_packet(void* data, int length) |
{ |
volatile oeth_regs *regs; |
regs = (oeth_regs *)(OETH_REG_BASE); |
|
volatile oeth_bd *tx_bd; |
volatile int i; |
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; |
tx_bd = (struct oeth_bd*) &tx_bd[next_tx_buf_num]; |
|
// If it's in use - wait |
while ((tx_bd->len_status & OETH_TX_BD_IRQ)); |
|
/* Clear all of the status flags. |
*/ |
tx_bd->len_status &= ~OETH_TX_BD_STATS; |
|
/* If the frame is short, tell CPM to pad it. |
*/ |
#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ |
if (length <= ETH_ZLEN) |
tx_bd->len_status |= OETH_TX_BD_PAD; |
else |
tx_bd->len_status &= ~OETH_TX_BD_PAD; |
|
#ifdef _ETH_RXTX_DATA_H_ |
// Set the address pointer to the place |
// in memory where the data is and transmit from there |
|
tx_bd->addr = (char*) &tx_data_array[tx_data_pointer&~(0x3)]; |
|
tx_data_pointer += length + 1; |
if (tx_data_pointer > (255*1024)) |
tx_data_pointer = 0; |
|
|
#else |
if (data){ |
//Copy the data into the transmit buffer, byte at a time |
char* data_p = (char*) data; |
char* data_b = (char*) tx_bd->addr; |
for(i=0;i<length;i++) |
{ |
data_b[i] = data_p[i]; |
} |
} |
#endif |
|
/* Set the length of the packet's data in the buffer descriptor */ |
tx_bd->len_status = (tx_bd->len_status & 0x0000ffff) | |
((length&0xffff) << 16); |
|
/* Send it on its way. Tell controller its ready, interrupt when sent |
* and to put the CRC on the end. |
*/ |
tx_bd->len_status |= (OETH_TX_BD_READY | OETH_TX_BD_CRC | OETH_TX_BD_IRQ); |
|
next_tx_buf_num = (next_tx_buf_num + 1) & OETH_TXBD_NUM_MASK; |
|
return; |
|
|
} |
|
/* The interrupt handler. |
*/ |
void |
oeth_interrupt(void) |
{ |
|
volatile oeth_regs *regs; |
regs = (oeth_regs *)(OETH_REG_BASE); |
|
uint int_events; |
int serviced; |
|
serviced = 0; |
|
/* Get the interrupt events that caused us to be here. |
*/ |
int_events = regs->int_src; |
regs->int_src = int_events; |
|
/* Handle receive event in its own function. |
*/ |
if (int_events & (OETH_INT_RXF | OETH_INT_RXE)) { |
serviced |= 0x1; |
oeth_rx(); |
} |
|
/* Handle transmit event in its own function. |
*/ |
if (int_events & (OETH_INT_TXB | OETH_INT_TXE)) { |
serviced |= 0x2; |
oeth_tx(); |
serviced |= 0x2; |
|
} |
|
/* Check for receive busy, i.e. packets coming but no place to |
* put them. |
*/ |
if (int_events & OETH_INT_BUSY) { |
serviced |= 0x4; |
if (!(int_events & (OETH_INT_RXF | OETH_INT_RXE))) |
oeth_rx(); |
} |
|
return; |
} |
|
|
|
static void |
oeth_rx(void) |
{ |
volatile oeth_regs *regs; |
regs = (oeth_regs *)(OETH_REG_BASE); |
|
volatile oeth_bd *rx_bdp; |
int pkt_len, i; |
int bad = 0; |
|
rx_bdp = ((oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM; |
|
|
/* Find RX buffers marked as having received data */ |
for(i = 0; i < OETH_RXBD_NUM; i++) |
{ |
bad=0; |
if(!(rx_bdp[i].len_status & OETH_RX_BD_EMPTY)){ /* Looking for NOT empty buffers desc. */ |
/* Check status for errors. |
*/ |
if (rx_bdp[i].len_status & (OETH_RX_BD_TOOLONG | OETH_RX_BD_SHORT)) { |
bad = 1; |
report(0xbaad0001); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_DRIBBLE) { |
bad = 1; |
report(0xbaad0002); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_CRCERR) { |
bad = 1; |
report(0xbaad0003); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_OVERRUN) { |
bad = 1; |
report(0xbaad0004); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_MISS) { |
report(0xbaad0005); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_LATECOL) { |
bad = 1; |
report(0xbaad0006); |
} |
if (bad) { |
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS; |
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY; |
exit(0xbaaaaaad); |
|
continue; |
} |
else { |
/* Process the incoming frame. |
*/ |
pkt_len = rx_bdp[i].len_status >> 16; |
|
/* finish up */ |
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS; /* Clear stats */ |
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY; /* Mark RX BD as empty */ |
rx_done++; |
} |
} |
} |
} |
|
|
|
static void |
oeth_tx(void) |
{ |
volatile oeth_bd *tx_bd; |
int i; |
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/ |
|
/* Go through the TX buffs, search for one that was just sent */ |
for(i = 0; i < OETH_TXBD_NUM; i++) |
{ |
/* Looking for buffer NOT ready for transmit. and IRQ enabled */ |
if( (!(tx_bd[i].len_status & (OETH_TX_BD_READY))) && (tx_bd[i].len_status & (OETH_TX_BD_IRQ)) ) |
{ |
/* Single threaded so no chance we have detected a buffer that has had its IRQ bit set but not its BD_READ flag. Maybe this won't work in linux */ |
tx_bd[i].len_status &= ~OETH_TX_BD_IRQ; |
|
/* Probably good to check for TX errors here */ |
|
/* set our test variable */ |
tx_done++; |
|
} |
} |
return; |
} |
|
// A function and defines to fill and transmit a packet |
#define MAX_TX_BUFFER 1532 |
static char tx_buffer[MAX_TX_BUFFER]; |
|
void |
fill_and_tx_call_packet(int size, int response_time) |
{ |
int i; |
|
volatile oeth_regs *regs; |
regs = (oeth_regs *)(OETH_REG_BASE); |
|
volatile oeth_bd *tx_bd; |
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; |
tx_bd = (volatile oeth_bd*) &tx_bd[next_tx_buf_num]; |
|
// If it's in use - wait |
while ((tx_bd->len_status & OETH_TX_BD_IRQ)); |
|
// Use rand() function to generate data for transmission |
// Assumption: ethernet buffer descriptors are 4byte aligned |
char* data_b = (char*) tx_bd->addr; |
// We will fill with words until there' less than a word to go |
int words_to_fill = size / sizeof(unsigned int); |
|
unsigned int* data_w = (unsigned int*) data_b; |
|
// Put first word as size of packet, second as response time |
data_w[0] = size; |
data_w[1] = response_time; |
|
for(i=2;i<words_to_fill;i++) |
data_w[i] = rand(); |
|
// Point data_b to offset wher word fills ended |
data_b += (words_to_fill * sizeof(unsigned int)); |
|
int leftover_size = size - (words_to_fill * sizeof(unsigned int)); |
|
for(i=0;i<leftover_size;i++) |
{ |
data_b[i] = rand() & 0xff; |
} |
|
tx_packet((void*)0, size); |
} |
|
// Send a packet, the very first byte of which will be read by the testbench |
// and used to indicate which test we'll use. |
void |
send_ethmac_rxtx_test_init_packet(char test) |
{ |
char cmd_tx_buffer[40]; |
cmd_tx_buffer[0] = test; |
tx_packet(cmd_tx_buffer, 40); // Smallest packet that can be sent (I think) |
} |
|
// Loop to check if a number is prime by doing mod divide of the number |
// to test by every number less than it |
int |
is_prime_number(unsigned long n) |
{ |
unsigned long c; |
if (n < 2) return 0; |
for(c=2;c<n;c++) |
if ((n % c) == 0) |
return 0; |
return 1; |
} |
|
|
int |
main () |
{ |
tx_data_pointer = 0; |
|
/* Initialise handler vector */ |
int_init(); |
|
/* Install ethernet interrupt handler, it is enabled here too */ |
int_add(ETH0_IRQ, oeth_interrupt, 0); |
|
/* Enable interrupts in supervisor register */ |
cpu_enable_user_interrupts(); |
|
/* Enable CPU timer */ |
cpu_enable_timer(); |
|
ethmac_setup(); /* Configure MAC, TX/RX BDs and enable RX and TX in MODER */ |
|
/* clear tx_done, the tx interrupt handler will set it when it's been |
transmitted */ |
tx_done = 0; |
rx_done = 0; |
|
ethphy_set_100mbit(0); |
|
send_ethmac_rxtx_test_init_packet(0x0); // 0x0 - call response test |
|
#define ETH_TX_MIN_PACKET_SIZE 512 |
#define ETH_TX_NUM_PACKETS (ETH_TX_MIN_PACKET_SIZE + 20) |
|
//int response_time = 150000; // Response time before response packet it sent |
// back (should be in nanoseconds). |
int response_time = 0; |
|
unsigned long num_to_check; |
for(num_to_check=ETH_TX_MIN_PACKET_SIZE; |
num_to_check<ETH_TX_NUM_PACKETS; |
num_to_check++) |
fill_and_tx_call_packet(num_to_check, response_time); |
|
|
// Wait a moment for the RX packet check to complete before switching off RX |
for(num_to_check=0;num_to_check=1000;num_to_check++); |
|
oeth_disable_rx(); |
|
// Now for 10mbit mode... |
ethphy_set_10mbit(0); |
|
oeth_enable_rx(); |
|
for(num_to_check=ETH_TX_MIN_PACKET_SIZE; |
num_to_check<ETH_TX_NUM_PACKETS; |
num_to_check++) |
fill_and_tx_call_packet(num_to_check, response_time); |
|
oeth_disable_rx(); |
|
// Go back to 100-mbit mode |
ethphy_set_100mbit(0); |
|
oeth_enable_rx(); |
|
for(num_to_check=ETH_TX_MIN_PACKET_SIZE; |
num_to_check<ETH_TX_NUM_PACKETS; |
num_to_check++) |
fill_and_tx_call_packet(num_to_check, response_time); |
|
exit(0x8000000d); |
|
} |
/s3adsp1800/sw/tests/ethmac/sim/ethmac-rxtx.c
0,0 → 1,671
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Interrupt-driven Ethernet MAC transmit test code //// |
//// //// |
//// Description //// |
//// Send packets while receiving packets //// |
//// //// |
//// Test data comes from pre-calculated array of random values, //// |
//// MAC TX buffer pointers are set to addresses in this array, //// |
//// saving copying the data around before transfers. //// |
//// //// |
//// Author(s): //// |
//// - jb, jb@orsoc.se, with parts taken from Linux kernel //// |
//// open_eth driver. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009 Authors and 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
#include "cpu-utils.h" |
#include "board.h" |
#include "int.h" |
#include "ethmac.h" |
#include "eth-phy-mii.h" |
|
volatile unsigned tx_done; |
volatile unsigned rx_done; |
static int next_tx_buf_num; |
|
/* Functions in this file */ |
void ethmac_setup(void); |
/* Interrupt functions */ |
void oeth_interrupt(void); |
static void oeth_rx(void); |
static void oeth_tx(void); |
|
/* Let the ethernet packets use a space beginning here for buffering */ |
#define ETH_BUFF_BASE 0x200000; |
|
|
#define RXBUFF_PREALLOC 1 |
#define TXBUFF_PREALLOC 1 |
//#undef RXBUFF_PREALLOC |
//#undef TXBUFF_PREALLOC |
|
/* The transmitter timeout |
*/ |
#define TX_TIMEOUT (2*HZ) |
|
/* Buffer number (must be 2^n) |
*/ |
#define OETH_RXBD_NUM 16 |
#define OETH_TXBD_NUM 16 |
#define OETH_RXBD_NUM_MASK (OETH_RXBD_NUM-1) |
#define OETH_TXBD_NUM_MASK (OETH_TXBD_NUM-1) |
|
/* Buffer size |
*/ |
#define OETH_RX_BUFF_SIZE 0x600-4 |
#define OETH_TX_BUFF_SIZE 0x600-4 |
|
/* Buffer size (if not XXBUF_PREALLOC |
*/ |
#define MAX_FRAME_SIZE 1518 |
|
/* The buffer descriptors track the ring buffers. |
*/ |
struct oeth_private { |
//struct sk_buff* rx_skbuff[OETH_RXBD_NUM]; |
//struct sk_buff* tx_skbuff[OETH_TXBD_NUM]; |
|
unsigned short tx_next; /* Next buffer to be sent */ |
unsigned short tx_last; /* Next buffer to be checked if packet sent */ |
unsigned short tx_full; /* Buffer ring fuul indicator */ |
unsigned short rx_cur; /* Next buffer to be checked if packet |
received */ |
|
oeth_regs *regs; /* Address of controller registers. */ |
oeth_bd *rx_bd_base; /* Address of Rx BDs. */ |
oeth_bd *tx_bd_base; /* Address of Tx BDs. */ |
|
// struct net_device_stats stats; |
}; |
|
#define PHYNUM 7 |
|
// Data array of data to transmit, tx_data_array[] |
//#include "eth-rxtx-data.h" // Not used |
int tx_data_pointer; |
|
|
void |
eth_mii_write(char phynum, short regnum, short data) |
{ |
static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE); |
regs->miiaddress = (regnum << 8) | phynum; |
regs->miitx_data = data; |
regs->miicommand = OETH_MIICOMMAND_WCTRLDATA; |
regs->miicommand = 0; |
while(regs->miistatus & OETH_MIISTATUS_BUSY); |
} |
|
short |
eth_mii_read(char phynum, short regnum) |
{ |
static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE); |
regs->miiaddress = (regnum << 8) | phynum; |
regs->miicommand = OETH_MIICOMMAND_RSTAT; |
regs->miicommand = 0; |
while(regs->miistatus & OETH_MIISTATUS_BUSY); |
|
return regs->miirx_data; |
} |
|
|
|
// Wait here until all packets have been transmitted |
void |
wait_until_all_tx_clear(void) |
{ |
int i; |
volatile oeth_bd *tx_bd; |
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/ |
|
int some_tx_waiting = 1; |
|
while (some_tx_waiting) |
{ |
some_tx_waiting = 0; |
/* Go through the TX buffs, search for unused one */ |
for(i = 0; i < OETH_TXBD_NUM; i++) { |
|
// Looking for buffer ready for transmit |
if((tx_bd[i].len_status & OETH_TX_BD_READY)) |
some_tx_waiting = 1; |
|
} |
} |
} |
|
|
void |
ethphy_set_10mbit(int phynum) |
{ |
wait_until_all_tx_clear(); |
// Hardset PHY to just use 10Mbit mode |
short cr = eth_mii_read(phynum, MII_BMCR); |
cr &= ~BMCR_ANENABLE; // Clear auto negotiate bit |
cr &= ~BMCR_SPEED100; // Clear fast eth. bit |
eth_mii_write(phynum, MII_BMCR, cr); |
} |
|
|
void |
ethphy_set_100mbit(int phynum) |
{ |
wait_until_all_tx_clear(); |
// Hardset PHY to just use 100Mbit mode |
short cr = eth_mii_read(phynum, MII_BMCR); |
cr |= BMCR_ANENABLE; // Clear auto negotiate bit |
cr |= BMCR_SPEED100; // Clear fast eth. bit |
eth_mii_write(phynum, MII_BMCR, cr); |
} |
|
|
void |
ethmac_setup(void) |
{ |
// from arch/or32/drivers/open_eth.c |
volatile oeth_regs *regs; |
|
regs = (oeth_regs *)(OETH_REG_BASE); |
|
/* Reset MII mode module */ |
regs->miimoder = OETH_MIIMODER_RST; /* MII Reset ON */ |
regs->miimoder &= ~OETH_MIIMODER_RST; /* MII Reset OFF */ |
regs->miimoder = 0x64; /* Clock divider for MII Management interface */ |
|
/* Reset the controller. |
*/ |
regs->moder = OETH_MODER_RST; /* Reset ON */ |
regs->moder &= ~OETH_MODER_RST; /* Reset OFF */ |
|
/* Setting TXBD base to OETH_TXBD_NUM. |
*/ |
regs->tx_bd_num = OETH_TXBD_NUM; |
|
|
/* Set min/max packet length |
*/ |
regs->packet_len = 0x00400600; |
|
/* Set IPGT register to recomended value |
*/ |
regs->ipgt = 0x12; |
|
/* Set IPGR1 register to recomended value |
*/ |
regs->ipgr1 = 0x0000000c; |
|
/* Set IPGR2 register to recomended value |
*/ |
regs->ipgr2 = 0x00000012; |
|
/* Set COLLCONF register to recomended value |
*/ |
regs->collconf = 0x000f003f; |
|
/* Set control module mode |
*/ |
#if 0 |
regs->ctrlmoder = OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW; |
#else |
regs->ctrlmoder = 0; |
#endif |
|
/* Clear MIIM registers */ |
regs->miitx_data = 0; |
regs->miiaddress = 0; |
regs->miicommand = 0; |
|
regs->mac_addr1 = ETH_MACADDR0 << 8 | ETH_MACADDR1; |
regs->mac_addr0 = ETH_MACADDR2 << 24 | ETH_MACADDR3 << 16 | ETH_MACADDR4 << 8 | ETH_MACADDR5; |
|
/* Clear all pending interrupts |
*/ |
regs->int_src = 0xffffffff; |
|
/* Promisc, IFG, CRCEn |
*/ |
regs->moder |= OETH_MODER_PRO | OETH_MODER_PAD | OETH_MODER_IFG | OETH_MODER_CRCEN | OETH_MODER_FULLD; |
|
/* Enable interrupt sources. |
*/ |
|
regs->int_mask = OETH_INT_MASK_TXB | |
OETH_INT_MASK_TXE | |
OETH_INT_MASK_RXF | |
OETH_INT_MASK_RXE | |
OETH_INT_MASK_BUSY | |
OETH_INT_MASK_TXC | |
OETH_INT_MASK_RXC; |
|
// Buffer setup stuff |
volatile oeth_bd *tx_bd, *rx_bd; |
int i,j,k; |
|
/* Initialize TXBD pointer |
*/ |
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; |
|
/* Initialize RXBD pointer |
*/ |
rx_bd = ((volatile oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM; |
|
/* Preallocated ethernet buffer setup */ |
unsigned long mem_addr = ETH_BUFF_BASE; /* Defined at top */ |
|
// Setup TX Buffers |
for(i = 0; i < OETH_TXBD_NUM; i++) { |
//tx_bd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC | OETH_RX_BD_IRQ; |
tx_bd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC; |
tx_bd[i].addr = mem_addr; |
mem_addr += OETH_TX_BUFF_SIZE; |
} |
tx_bd[OETH_TXBD_NUM - 1].len_status |= OETH_TX_BD_WRAP; |
|
// Setup RX buffers |
for(i = 0; i < OETH_RXBD_NUM; i++) { |
rx_bd[i].len_status = OETH_RX_BD_EMPTY | OETH_RX_BD_IRQ; // Init. with IRQ |
rx_bd[i].addr = mem_addr; |
mem_addr += OETH_RX_BUFF_SIZE; |
} |
rx_bd[OETH_RXBD_NUM - 1].len_status |= OETH_RX_BD_WRAP; // Last buffer wraps |
|
/* Enable RX and TX in MAC |
*/ |
regs->moder &= ~(OETH_MODER_RXEN | OETH_MODER_TXEN); |
regs->moder |= OETH_MODER_RXEN | OETH_MODER_TXEN; |
|
next_tx_buf_num = 0; // init tx buffer pointer |
|
return; |
} |
|
// Enable RX in ethernet MAC |
void |
oeth_enable_rx(void) |
{ |
volatile oeth_regs *regs; |
regs = (oeth_regs *)(OETH_REG_BASE); |
regs->moder |= OETH_MODER_RXEN; |
} |
|
// Disable RX in ethernet MAC |
void |
oeth_disable_rx(void) |
{ |
volatile oeth_regs *regs; |
regs = (oeth_regs *)(OETH_REG_BASE); |
regs->moder &= ~(OETH_MODER_RXEN); |
} |
|
|
/* Setup buffer descriptors with data */ |
/* length is in BYTES */ |
void tx_packet(void* data, int length) |
{ |
volatile oeth_regs *regs; |
regs = (oeth_regs *)(OETH_REG_BASE); |
|
volatile oeth_bd *tx_bd; |
volatile int i; |
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; |
tx_bd = (struct oeth_bd*) &tx_bd[next_tx_buf_num]; |
|
// If it's in use - wait |
while ((tx_bd->len_status & OETH_TX_BD_IRQ)); |
|
/* Clear all of the status flags. |
*/ |
tx_bd->len_status &= ~OETH_TX_BD_STATS; |
|
/* If the frame is short, tell CPM to pad it. |
*/ |
#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ |
if (length <= ETH_ZLEN) |
tx_bd->len_status |= OETH_TX_BD_PAD; |
else |
tx_bd->len_status &= ~OETH_TX_BD_PAD; |
|
#ifdef _ETH_RXTX_DATA_H_ |
// Set the address pointer to the place |
// in memory where the data is and transmit from there |
|
tx_bd->addr = (char*) &tx_data_array[tx_data_pointer&~(0x3)]; |
|
tx_data_pointer += length + 1; |
if (tx_data_pointer > (255*1024)) |
tx_data_pointer = 0; |
|
|
#else |
if (data){ |
//Copy the data into the transmit buffer, byte at a time |
char* data_p = (char*) data; |
char* data_b = (char*) tx_bd->addr; |
for(i=0;i<length;i++) |
{ |
data_b[i] = data_p[i]; |
} |
} |
#endif |
|
/* Set the length of the packet's data in the buffer descriptor */ |
tx_bd->len_status = (tx_bd->len_status & 0x0000ffff) | |
((length&0xffff) << 16); |
|
/* Send it on its way. Tell controller its ready, interrupt when sent |
* and to put the CRC on the end. |
*/ |
tx_bd->len_status |= (OETH_TX_BD_READY | OETH_TX_BD_CRC | OETH_TX_BD_IRQ); |
|
next_tx_buf_num = (next_tx_buf_num + 1) & OETH_TXBD_NUM_MASK; |
|
return; |
|
|
} |
|
/* The interrupt handler. |
*/ |
void |
oeth_interrupt(void) |
{ |
|
volatile oeth_regs *regs; |
regs = (oeth_regs *)(OETH_REG_BASE); |
|
uint int_events; |
int serviced; |
|
serviced = 0; |
|
/* Get the interrupt events that caused us to be here. |
*/ |
int_events = regs->int_src; |
regs->int_src = int_events; |
|
/* Handle receive event in its own function. |
*/ |
if (int_events & (OETH_INT_RXF | OETH_INT_RXE)) { |
serviced |= 0x1; |
oeth_rx(); |
} |
|
/* Handle transmit event in its own function. |
*/ |
if (int_events & (OETH_INT_TXB | OETH_INT_TXE)) { |
serviced |= 0x2; |
oeth_tx(); |
serviced |= 0x2; |
|
} |
|
/* Check for receive busy, i.e. packets coming but no place to |
* put them. |
*/ |
if (int_events & OETH_INT_BUSY) { |
serviced |= 0x4; |
if (!(int_events & (OETH_INT_RXF | OETH_INT_RXE))) |
oeth_rx(); |
} |
|
return; |
} |
|
|
|
static void |
oeth_rx(void) |
{ |
volatile oeth_regs *regs; |
regs = (oeth_regs *)(OETH_REG_BASE); |
|
volatile oeth_bd *rx_bdp; |
int pkt_len, i; |
int bad = 0; |
|
rx_bdp = ((oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM; |
|
|
/* Find RX buffers marked as having received data */ |
for(i = 0; i < OETH_RXBD_NUM; i++) |
{ |
bad=0; |
if(!(rx_bdp[i].len_status & OETH_RX_BD_EMPTY)){ /* Looking for NOT empty buffers desc. */ |
/* Check status for errors. |
*/ |
if (rx_bdp[i].len_status & (OETH_RX_BD_TOOLONG | OETH_RX_BD_SHORT)) { |
bad = 1; |
report(0xbaad0001); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_DRIBBLE) { |
bad = 1; |
report(0xbaad0002); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_CRCERR) { |
bad = 1; |
report(0xbaad0003); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_OVERRUN) { |
bad = 1; |
report(0xbaad0004); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_MISS) { |
report(0xbaad0005); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_LATECOL) { |
bad = 1; |
report(0xbaad0006); |
} |
if (bad) { |
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS; |
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY; |
exit(0xbaaaaaad); |
|
continue; |
} |
else { |
/* Process the incoming frame. |
*/ |
pkt_len = rx_bdp[i].len_status >> 16; |
|
/* finish up */ |
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS; /* Clear stats */ |
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY; /* Mark RX BD as empty */ |
rx_done++; |
} |
} |
} |
} |
|
|
|
static void |
oeth_tx(void) |
{ |
volatile oeth_bd *tx_bd; |
int i; |
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/ |
|
/* Go through the TX buffs, search for one that was just sent */ |
for(i = 0; i < OETH_TXBD_NUM; i++) |
{ |
/* Looking for buffer NOT ready for transmit. and IRQ enabled */ |
if( (!(tx_bd[i].len_status & (OETH_TX_BD_READY))) && (tx_bd[i].len_status & (OETH_TX_BD_IRQ)) ) |
{ |
/* Single threaded so no chance we have detected a buffer that has had its IRQ bit set but not its BD_READ flag. Maybe this won't work in linux */ |
tx_bd[i].len_status &= ~OETH_TX_BD_IRQ; |
|
/* Probably good to check for TX errors here */ |
|
/* set our test variable */ |
tx_done++; |
|
} |
} |
return; |
} |
|
// A function and defines to fill and transmit a packet |
#define MAX_TX_BUFFER 1532 |
static char tx_buffer[MAX_TX_BUFFER]; |
|
void |
fill_and_tx_packet(int size) |
{ |
int i; |
|
volatile oeth_regs *regs; |
regs = (oeth_regs *)(OETH_REG_BASE); |
|
volatile oeth_bd *tx_bd; |
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; |
tx_bd = (volatile oeth_bd*) &tx_bd[next_tx_buf_num]; |
|
// If it's in use - wait |
while ((tx_bd->len_status & OETH_TX_BD_IRQ)); |
|
// Use rand() function to generate data for transmission |
// Assumption: ethernet buffer descriptors are 4byte aligned |
char* data_b = (char*) tx_bd->addr; |
// We will fill with words until there' less than a word to go |
int words_to_fill = size / sizeof(unsigned int); |
|
unsigned int* data_w = (unsigned int*) data_b; |
|
for(i=0;i<words_to_fill;i++) |
data_w[i] = rand(); |
|
// Point data_b to offset wher word fills ended |
data_b += (words_to_fill * sizeof(unsigned int)); |
|
int leftover_size = size - (words_to_fill * sizeof(unsigned int)); |
|
for(i=0;i<leftover_size;i++) |
{ |
data_b[i] = rand() & 0xff; |
} |
|
tx_packet((void*)0, size); |
} |
|
// Send a packet, the very first byte of which will be read by the testbench |
// and used to indicate which test we'll use. |
void |
send_ethmac_rxtx_test_init_packet(char test) |
{ |
char cmd_tx_buffer[40]; |
cmd_tx_buffer[0] = test; |
tx_packet(cmd_tx_buffer, 40); // Smallest packet that can be sent (I think) |
} |
|
// Loop to check if a number is prime by doing mod divide of the number |
// to test by every number less than it |
int |
is_prime_number(unsigned long n) |
{ |
unsigned long c; |
if (n < 2) return 0; |
for(c=2;c<n;c++) |
if ((n % c) == 0) |
return 0; |
return 1; |
} |
|
|
int |
main () |
{ |
tx_data_pointer = 0; |
|
/* Initialise handler vector */ |
int_init(); |
|
/* Install ethernet interrupt handler, it is enabled here too */ |
int_add(ETH0_IRQ, oeth_interrupt, 0); |
|
/* Enable interrupts in supervisor register */ |
cpu_enable_user_interrupts(); |
|
/* Enable CPU timer */ |
cpu_enable_timer(); |
|
ethmac_setup(); /* Configure MAC, TX/RX BDs and enable RX and TX in MODER */ |
|
/* clear tx_done, the tx interrupt handler will set it when it's been |
transmitted */ |
tx_done = 0; |
rx_done = 0; |
|
ethphy_set_100mbit(0); |
|
send_ethmac_rxtx_test_init_packet(0xff); // Test value of 0xFF |
|
//oeth_enable_rx(); |
|
#define ETH_TX_MIN_PACKET_SIZE 512 |
#define ETH_TX_NUM_PACKETS (ETH_TX_MIN_PACKET_SIZE + 32) |
|
unsigned long num_to_check; |
for(num_to_check=ETH_TX_MIN_PACKET_SIZE; |
num_to_check<ETH_TX_NUM_PACKETS; |
num_to_check++) |
fill_and_tx_packet(num_to_check); |
|
oeth_disable_rx(); |
|
// Now for 10mbit mode... |
ethphy_set_10mbit(0); |
|
oeth_enable_rx(); |
|
for(num_to_check=ETH_TX_MIN_PACKET_SIZE; |
num_to_check<ETH_TX_NUM_PACKETS; |
num_to_check++) |
fill_and_tx_packet(num_to_check); |
|
oeth_disable_rx(); |
|
// Go back to 100-mbit mode |
ethphy_set_100mbit(0); |
|
oeth_enable_rx(); |
|
for(num_to_check=ETH_TX_MIN_PACKET_SIZE; |
num_to_check<ETH_TX_NUM_PACKETS; |
num_to_check++) |
fill_and_tx_packet(num_to_check); |
|
exit(0x8000000d); |
|
} |
/s3adsp1800/sw/tests/ethmac/sim/ethmac-rx.c
0,0 → 1,470
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Interrupt-driven Ethernet MAC test code //// |
//// //// |
//// Description //// |
//// Do ethernet receive path testing //// |
//// Relies on testbench to provide simulus - expects at least //// |
//// 256 packets to be sent. //// |
//// //// |
//// Author(s): //// |
//// - Julius Baxter, julius@opencores.org //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009 Authors and 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
#include "cpu-utils.h" |
#include "board.h" |
#include "int.h" |
#include "ethmac.h" |
#include "eth-phy-mii.h" |
|
volatile unsigned tx_done; |
volatile unsigned rx_done; |
|
/* Functions in this file */ |
void ethmac_setup(void); |
void oeth_dump_bds(); |
/* Interrupt functions */ |
void oeth_interrupt(void); |
static void oeth_rx(void); |
static void oeth_tx(void); |
/* Function to calculate checksum of ping responses we send */ |
unsigned short calculate_checksum(char* dats, unsigned int len) ; |
|
/* Let the ethernet packets use a space beginning here for buffering */ |
#define ETH_BUFF_BASE 0x200000; |
|
#define RXBUFF_PREALLOC 1 |
#define TXBUFF_PREALLOC 1 |
|
/* The transmitter timeout |
*/ |
#define TX_TIMEOUT (2*HZ) |
|
/* Buffer number (must be 2^n) |
* Note: if changing these, must also change settings in eth_stim.v testbench |
* file! |
*/ |
#define OETH_RXBD_NUM 16 |
#define OETH_TXBD_NUM 16 |
#define OETH_RXBD_NUM_MASK (OETH_RXBD_NUM-1) |
#define OETH_TXBD_NUM_MASK (OETH_TXBD_NUM-1) |
|
/* Buffer size |
*/ |
#define OETH_RX_BUFF_SIZE 0x600 |
#define OETH_TX_BUFF_SIZE 0x600 |
|
/* Buffer size (if not XXBUF_PREALLOC |
*/ |
#define MAX_FRAME_SIZE 1518 |
|
/* The buffer descriptors track the ring buffers. |
*/ |
struct oeth_private { |
//struct sk_buff* rx_skbuff[OETH_RXBD_NUM]; |
//struct sk_buff* tx_skbuff[OETH_TXBD_NUM]; |
|
unsigned short tx_next; /* Next buffer to be sent */ |
unsigned short tx_last; /* Next buffer to be checked if packet sent */ |
unsigned short tx_full; /* Buffer ring fuul indicator */ |
unsigned short rx_cur; /* Next buffer to be checked if packet received */ |
|
oeth_regs *regs; /* Address of controller registers. */ |
oeth_bd *rx_bd_base; /* Address of Rx BDs. */ |
oeth_bd *tx_bd_base; /* Address of Tx BDs. */ |
|
// struct net_device_stats stats; |
}; |
|
|
char CHECKSUM_BUFFER[OETH_RX_BUFF_SIZE]; // Big enough to hold a packet |
|
#define PHYNUM 7 |
|
void ethmac_setup(void) |
{ |
// from arch/or32/drivers/open_eth.c |
volatile oeth_regs *regs; |
|
regs = (oeth_regs *)(OETH_REG_BASE); |
|
/* Reset MII mode module */ |
regs->miimoder = OETH_MIIMODER_RST; /* MII Reset ON */ |
regs->miimoder &= ~OETH_MIIMODER_RST; /* MII Reset OFF */ |
regs->miimoder = 0x64; /* Clock divider for MII Management interface */ |
|
/* Reset the controller. |
*/ |
regs->moder = OETH_MODER_RST; /* Reset ON */ |
regs->moder &= ~OETH_MODER_RST; /* Reset OFF */ |
|
/* Setting TXBD base to OETH_TXBD_NUM. |
*/ |
regs->tx_bd_num = OETH_TXBD_NUM; |
|
|
/* Set min/max packet length |
*/ |
regs->packet_len = 0x00400600; |
|
/* Set IPGT register to recomended value |
*/ |
regs->ipgt = 0x12; |
|
/* Set IPGR1 register to recomended value |
*/ |
regs->ipgr1 = 0x0000000c; |
|
/* Set IPGR2 register to recomended value |
*/ |
regs->ipgr2 = 0x00000012; |
|
/* Set COLLCONF register to recomended value |
*/ |
regs->collconf = 0x000f003f; |
|
/* Set control module mode |
*/ |
#if 0 |
regs->ctrlmoder = OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW; |
#else |
regs->ctrlmoder = 0; |
#endif |
|
/* Clear MIIM registers */ |
regs->miitx_data = 0; |
regs->miiaddress = 0; |
regs->miicommand = 0; |
|
regs->mac_addr1 = ETH_MACADDR0 << 8 | ETH_MACADDR1; |
regs->mac_addr0 = ETH_MACADDR2 << 24 | ETH_MACADDR3 << 16 | ETH_MACADDR4 << 8 | ETH_MACADDR5; |
|
/* Clear all pending interrupts |
*/ |
regs->int_src = 0xffffffff; |
|
/* Promisc, IFG, CRCEn |
*/ |
regs->moder |= OETH_MODER_PRO | OETH_MODER_PAD | OETH_MODER_IFG | OETH_MODER_CRCEN | OETH_MODER_FULLD; |
|
/* Enable interrupt sources. |
*/ |
|
regs->int_mask = OETH_INT_MASK_TXB | |
OETH_INT_MASK_TXE | |
OETH_INT_MASK_RXF | |
OETH_INT_MASK_RXE | |
OETH_INT_MASK_BUSY | |
OETH_INT_MASK_TXC | |
OETH_INT_MASK_RXC; |
|
// Buffer setup stuff |
volatile oeth_bd *tx_bd, *rx_bd; |
int i,j,k; |
|
/* Initialize TXBD pointer |
*/ |
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; |
|
/* Initialize RXBD pointer |
*/ |
rx_bd = ((volatile oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM; |
|
/* Preallocated ethernet buffer setup */ |
unsigned long mem_addr = ETH_BUFF_BASE; /* Defined at top */ |
|
// Setup TX Buffers |
for(i = 0; i < OETH_TXBD_NUM; i++) { |
//tx_bd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC | OETH_RX_BD_IRQ; |
tx_bd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC; |
tx_bd[i].addr = mem_addr; |
mem_addr += OETH_TX_BUFF_SIZE; |
} |
tx_bd[OETH_TXBD_NUM - 1].len_status |= OETH_TX_BD_WRAP; |
|
// Setup RX buffers |
for(i = 0; i < OETH_RXBD_NUM; i++) { |
rx_bd[i].len_status = OETH_RX_BD_EMPTY | OETH_RX_BD_IRQ; // Init. with IRQ |
rx_bd[i].addr = mem_addr; |
mem_addr += OETH_RX_BUFF_SIZE; |
} |
rx_bd[OETH_RXBD_NUM - 1].len_status |= OETH_RX_BD_WRAP; // Last buffer wraps |
|
/* Enable just the receiver |
*/ |
regs->moder &= ~(OETH_MODER_RXEN | OETH_MODER_TXEN); |
regs->moder |= OETH_MODER_RXEN /* | OETH_MODER_TXEN*/; |
|
return; |
} |
|
void |
ethmac_halt(void) |
{ |
volatile oeth_regs *regs; |
|
regs = (oeth_regs *)(OETH_REG_BASE); |
|
// Disable receive and transmit |
regs->moder &= ~(OETH_MODER_RXEN | OETH_MODER_TXEN); |
|
} |
|
|
/* The interrupt handler. |
*/ |
void |
oeth_interrupt(void) |
{ |
|
volatile oeth_regs *regs; |
regs = (oeth_regs *)(OETH_REG_BASE); |
|
uint int_events; |
int serviced; |
|
serviced = 0; |
|
/* Get the interrupt events that caused us to be here. |
*/ |
int_events = regs->int_src; |
regs->int_src = int_events; |
|
|
/* Handle receive event in its own function. |
*/ |
if (int_events & (OETH_INT_RXF | OETH_INT_RXE)) { |
serviced |= 0x1; |
oeth_rx(); |
} |
|
/* Handle transmit event in its own function. |
*/ |
if (int_events & (OETH_INT_TXB | OETH_INT_TXE)) { |
serviced |= 0x2; |
oeth_tx(); |
serviced |= 0x2; |
|
} |
|
/* Check for receive busy, i.e. packets coming but no place to |
* put them. |
*/ |
if (int_events & OETH_INT_BUSY) { |
serviced |= 0x4; |
if (!(int_events & (OETH_INT_RXF | OETH_INT_RXE))) |
oeth_rx(); |
} |
|
return; |
} |
|
|
|
static void |
oeth_rx(void) |
{ |
volatile oeth_regs *regs; |
regs = (oeth_regs *)(OETH_REG_BASE); |
|
volatile oeth_bd *rx_bdp; |
int pkt_len, i; |
int bad = 0; |
|
rx_bdp = ((oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM; |
|
/* Find RX buffers marked as having received data */ |
for(i = 0; i < OETH_RXBD_NUM; i++) |
{ |
bad=0; |
/* Looking for buffer descriptors marked not empty */ |
if(!(rx_bdp[i].len_status & OETH_RX_BD_EMPTY)){ |
/* Check status for errors. |
*/ |
report(i); |
report(rx_bdp[i].len_status); |
if (rx_bdp[i].len_status & (OETH_RX_BD_TOOLONG | OETH_RX_BD_SHORT)) { |
bad = 1; |
report(0xbaad0001); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_DRIBBLE) { |
bad = 1; |
report(0xbaad0002); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_CRCERR) { |
bad = 1; |
report(0xbaad0003); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_OVERRUN) { |
bad = 1; |
report(0xbaad0004); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_MISS) { |
report(0xbaad0005); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_LATECOL) { |
bad = 1; |
report(0xbaad0006); |
} |
if (bad) { |
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS; |
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY; |
//exit(0xbaaaaaad); |
|
continue; |
} |
else { |
/* |
* Process the incoming frame. |
*/ |
pkt_len = rx_bdp[i].len_status >> 16; |
|
// Do a bit of work - ie. copy it, process it |
memcpy(CHECKSUM_BUFFER, rx_bdp[i].addr, pkt_len); |
report(0xc4eccccc); |
report(calculate_checksum(CHECKSUM_BUFFER, pkt_len)); |
|
/* finish up */ |
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS; /* Clear stats */ |
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY; /* Mark RX BD as empty */ |
rx_done++; |
report(rx_done); |
} |
} |
} |
} |
|
// Calculate checksum on received data. |
// From http://lkml.indiana.edu/hypermail/linux/kernel/9612.3/0060.html |
unsigned short calculate_checksum(char* dats, unsigned int len) |
{ |
unsigned int itr; |
unsigned long accum = 0; |
unsigned long longsum; |
|
// Sum all pairs of data |
for(itr=0;itr<(len & ~0x1);itr+=2) |
accum += (unsigned long)(((dats[itr]<<8)&0xff00)|(dats[itr+1]&0x00ff)); |
|
if (len & 0x1) // Do leftover |
accum += (unsigned long) ((dats[itr-1]<<8)&0xff00); |
|
longsum = (unsigned long) (accum & 0xffff); |
longsum += (unsigned long) (accum >> 16); // Sum the carries |
longsum += (longsum >> 16); |
return (unsigned short)((longsum ^ 0xffff) & 0xffff); |
|
} |
|
|
static void |
oeth_tx(void) |
{ |
volatile oeth_bd *tx_bd; |
int i; |
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/ |
|
/* Go through the TX buffs, search for one that was just sent */ |
for(i = 0; i < OETH_TXBD_NUM; i++) |
{ |
/* Looking for buffer NOT ready for transmit. and IRQ enabled */ |
if( (!(tx_bd[i].len_status & (OETH_TX_BD_READY))) && (tx_bd[i].len_status & (OETH_TX_BD_IRQ)) ) |
{ |
/* Single threaded so no chance we have detected a buffer that has had its IRQ bit set but not its BD_READ flag. Maybe this won't work in linux */ |
tx_bd[i].len_status &= ~OETH_TX_BD_IRQ; |
|
/* Probably good to check for TX errors here */ |
|
/* set our test variable */ |
tx_done = 1; |
|
} |
} |
return; |
} |
|
// Loop to check if a number is prime by doing mod divide of the number |
// to test by every number less than it |
int |
is_prime_number(unsigned long n) |
{ |
unsigned long c; |
if (n < 2) return 0; |
for(c=2;c<n;c++) |
if ((n % c) == 0) |
return 0; |
return 1; |
} |
|
int |
main () |
{ |
|
/* Initialise handler vector */ |
int_init(); |
|
/* Install ethernet interrupt handler, it is enabled here too */ |
int_add(ETH0_IRQ, oeth_interrupt, 0); |
|
/* Enable interrupts in supervisor register */ |
cpu_enable_user_interrupts(); |
|
/* Enable CPU timer */ |
cpu_enable_timer(); |
|
rx_done = 0; |
|
ethmac_setup(); /* Configure MAC, TX/RX BDs and enable RX in MODER */ |
|
#define NUM_PRIMES_TO_CHECK 1000 |
#define RX_TEST_LENGTH_PACKETS 12 |
|
char prime_check_results[NUM_PRIMES_TO_CHECK]; |
unsigned long num_to_check; |
|
for(num_to_check=2;num_to_check<NUM_PRIMES_TO_CHECK;num_to_check++) |
{ |
prime_check_results[num_to_check-2] |
= (char) is_prime_number(num_to_check); |
report(num_to_check | (0x1e<<24)); |
report(prime_check_results[num_to_check-2] | (0x2e<<24)); |
// Check number of packets received, testbench will hopefully send at |
// least this many packets |
if (rx_done >= (RX_TEST_LENGTH_PACKETS - 1)) |
exit(0x8000000d); |
} |
|
ethmac_halt(); |
|
exit(0x8000000d); |
|
return 0; |
} |
/s3adsp1800/sw/tests/ethmac/sim/ethmac-tx.c
0,0 → 1,589
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Interrupt-driven Ethernet MAC transmit test code //// |
//// //// |
//// Description //// |
//// Transmits packets, testing both 100mbit and 10mbit modes. //// |
//// Expects testbench to be checking each packet sent. //// |
//// Define, ETH_TX_TEST_LENGTH, set further down, controls how //// |
//// many packets the test will send. //// |
//// //// |
//// Author(s): //// |
//// - jb, jb@orsoc.se, with parts taken from Linux kernel //// |
//// open_eth driver. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009 Authors and 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
#include "cpu-utils.h" |
#include "board.h" |
#include "int.h" |
#include "ethmac.h" |
#include "eth-phy-mii.h" |
|
volatile unsigned tx_done; |
volatile unsigned rx_done; |
static int next_tx_buf_num; |
|
/* Functions in this file */ |
void ethmac_setup(void); |
/* Interrupt functions */ |
void oeth_interrupt(void); |
static void oeth_rx(void); |
static void oeth_tx(void); |
|
/* Let the ethernet packets use a space beginning here for buffering */ |
#define ETH_BUFF_BASE 0x200000; |
|
#define RXBUFF_PREALLOC 1 |
#define TXBUFF_PREALLOC 1 |
//#undef RXBUFF_PREALLOC |
//#undef TXBUFF_PREALLOC |
|
/* The transmitter timeout |
*/ |
#define TX_TIMEOUT (2*HZ) |
|
/* Buffer number (must be 2^n) |
*/ |
#define OETH_RXBD_NUM 16 |
#define OETH_TXBD_NUM 16 |
#define OETH_RXBD_NUM_MASK (OETH_RXBD_NUM-1) |
#define OETH_TXBD_NUM_MASK (OETH_TXBD_NUM-1) |
|
/* Buffer size |
*/ |
#define OETH_RX_BUFF_SIZE 0x600 - 4 |
#define OETH_TX_BUFF_SIZE 0x600 - 4 |
|
/* Buffer size (if not XXBUF_PREALLOC |
*/ |
#define MAX_FRAME_SIZE 1518 |
|
/* The buffer descriptors track the ring buffers. |
*/ |
struct oeth_private { |
|
unsigned short tx_next;/* Next buffer to be sent */ |
unsigned short tx_last;/* Next buffer to be checked if packet sent */ |
unsigned short tx_full;/* Buffer ring fuul indicator */ |
unsigned short rx_cur; /* Next buffer to check if packet received */ |
|
oeth_regs *regs; /* Address of controller registers. */ |
oeth_bd *rx_bd_base; /* Address of Rx BDs. */ |
oeth_bd *tx_bd_base; /* Address of Tx BDs. */ |
|
// struct net_device_stats stats; |
}; |
|
|
// Data array of data to transmit, tx_data_array[] |
// Not included in ORPSoC - #include "eth-rxtx-data.h" |
//int tx_data_pointer; |
|
#define PHYNUM 7 |
|
void |
eth_mii_write(char phynum, short regnum, short data) |
{ |
static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE); |
regs->miiaddress = (regnum << 8) | phynum; |
regs->miitx_data = data; |
regs->miicommand = OETH_MIICOMMAND_WCTRLDATA; |
regs->miicommand = 0; |
while(regs->miistatus & OETH_MIISTATUS_BUSY); |
} |
|
short |
eth_mii_read(char phynum, short regnum) |
{ |
static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE); |
regs->miiaddress = (regnum << 8) | phynum; |
regs->miicommand = OETH_MIICOMMAND_RSTAT; |
regs->miicommand = 0; |
while(regs->miistatus & OETH_MIISTATUS_BUSY); |
|
return regs->miirx_data; |
} |
|
|
// Wait here until all packets have been transmitted |
void wait_until_all_tx_clear(void) |
{ |
|
int i; |
volatile oeth_bd *tx_bd; |
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/ |
|
int some_tx_waiting = 1; |
|
while (some_tx_waiting) |
{ |
some_tx_waiting = 0; |
/* Go through the TX buffs, search for unused one */ |
for(i = 0; i < OETH_TXBD_NUM; i++) { |
|
if((tx_bd[i].len_status & OETH_TX_BD_READY)) // Looking for buffer ready for transmit |
some_tx_waiting = 1; |
|
} |
} |
|
} |
|
|
void |
ethphy_set_10mbit(int phynum) |
{ |
wait_until_all_tx_clear(); |
// Hardset PHY to just use 10Mbit mode |
short cr = eth_mii_read(phynum, MII_BMCR); |
cr &= ~BMCR_ANENABLE; // Clear auto negotiate bit |
cr &= ~BMCR_SPEED100; // Clear fast eth. bit |
eth_mii_write(phynum, MII_BMCR, cr); |
} |
|
|
void |
ethphy_set_100mbit(int phynum) |
{ |
wait_until_all_tx_clear(); |
// Hardset PHY to just use 100Mbit mode |
short cr = eth_mii_read(phynum, MII_BMCR); |
cr |= BMCR_ANENABLE; // Clear auto negotiate bit |
cr |= BMCR_SPEED100; // Clear fast eth. bit |
eth_mii_write(phynum, MII_BMCR, cr); |
} |
|
|
void ethmac_setup(void) |
{ |
// from arch/or32/drivers/open_eth.c |
volatile oeth_regs *regs; |
|
regs = (oeth_regs *)(OETH_REG_BASE); |
|
/* Reset MII mode module */ |
regs->miimoder = OETH_MIIMODER_RST; /* MII Reset ON */ |
regs->miimoder &= ~OETH_MIIMODER_RST; /* MII Reset OFF */ |
regs->miimoder = 0x64; /* Clock divider for MII Management interface */ |
|
/* Reset the controller. |
*/ |
regs->moder = OETH_MODER_RST; /* Reset ON */ |
regs->moder &= ~OETH_MODER_RST; /* Reset OFF */ |
|
/* Setting TXBD base to OETH_TXBD_NUM. |
*/ |
regs->tx_bd_num = OETH_TXBD_NUM; |
|
|
/* Set min/max packet length |
*/ |
regs->packet_len = 0x00400600; |
|
/* Set IPGT register to recomended value |
*/ |
regs->ipgt = 0x12; |
|
/* Set IPGR1 register to recomended value |
*/ |
regs->ipgr1 = 0x0000000c; |
|
/* Set IPGR2 register to recomended value |
*/ |
regs->ipgr2 = 0x00000012; |
|
/* Set COLLCONF register to recomended value |
*/ |
regs->collconf = 0x000f003f; |
|
/* Set control module mode |
*/ |
#if 0 |
regs->ctrlmoder = OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW; |
#else |
regs->ctrlmoder = 0; |
#endif |
|
/* Clear MIIM registers */ |
regs->miitx_data = 0; |
regs->miiaddress = 0; |
regs->miicommand = 0; |
|
regs->mac_addr1 = ETH_MACADDR0 << 8 | ETH_MACADDR1; |
regs->mac_addr0 = ETH_MACADDR2 << 24 | ETH_MACADDR3 << 16 | ETH_MACADDR4 << 8 | ETH_MACADDR5; |
|
/* Clear all pending interrupts |
*/ |
regs->int_src = 0xffffffff; |
|
/* Promisc, IFG, CRCEn |
*/ |
regs->moder |= OETH_MODER_PRO | OETH_MODER_PAD | OETH_MODER_IFG | OETH_MODER_CRCEN | OETH_MODER_FULLD; |
|
/* Enable interrupt sources. |
*/ |
|
regs->int_mask = OETH_INT_MASK_TXB | |
OETH_INT_MASK_TXE | |
OETH_INT_MASK_RXF | |
OETH_INT_MASK_RXE | |
OETH_INT_MASK_BUSY | |
OETH_INT_MASK_TXC | |
OETH_INT_MASK_RXC; |
|
// Buffer setup stuff |
volatile oeth_bd *tx_bd, *rx_bd; |
int i,j,k; |
|
/* Initialize TXBD pointer |
*/ |
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; |
|
/* Initialize RXBD pointer |
*/ |
rx_bd = ((volatile oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM; |
|
/* Preallocated ethernet buffer setup */ |
unsigned long mem_addr = ETH_BUFF_BASE; /* Defined at top */ |
|
// Setup TX Buffers |
for(i = 0; i < OETH_TXBD_NUM; i++) { |
//tx_bd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC | OETH_RX_BD_IRQ; |
tx_bd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC; |
tx_bd[i].addr = mem_addr; |
mem_addr += OETH_TX_BUFF_SIZE; |
} |
tx_bd[OETH_TXBD_NUM - 1].len_status |= OETH_TX_BD_WRAP; |
|
// Setup RX buffers |
for(i = 0; i < OETH_RXBD_NUM; i++) { |
rx_bd[i].len_status = OETH_RX_BD_EMPTY | OETH_RX_BD_IRQ; // Init. with IRQ |
rx_bd[i].addr = mem_addr; |
mem_addr += OETH_RX_BUFF_SIZE; |
} |
rx_bd[OETH_RXBD_NUM - 1].len_status |= OETH_RX_BD_WRAP; // Last buffer wraps |
|
/* Enable JUST the transmiter |
*/ |
regs->moder &= ~(OETH_MODER_RXEN | OETH_MODER_TXEN); |
regs->moder |= /*OETH_MODER_RXEN |*/ OETH_MODER_TXEN; |
|
next_tx_buf_num = 0; // init tx buffer pointer |
|
return; |
} |
|
|
|
/* Setup buffer descriptors with data */ |
/* length is in BYTES */ |
void tx_packet(void* data, int length) |
{ |
volatile oeth_regs *regs; |
regs = (oeth_regs *)(OETH_REG_BASE); |
|
volatile oeth_bd *tx_bd; |
volatile int i; |
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; |
tx_bd = (struct oeth_bd*) &tx_bd[next_tx_buf_num]; |
|
// If it's in use - wait |
while ((tx_bd->len_status & OETH_TX_BD_IRQ)); |
|
/* Clear all of the status flags. |
*/ |
tx_bd->len_status &= ~OETH_TX_BD_STATS; |
|
/* If the frame is short, tell CPM to pad it. |
*/ |
#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ |
if (length <= ETH_ZLEN) |
tx_bd->len_status |= OETH_TX_BD_PAD; |
else |
tx_bd->len_status &= ~OETH_TX_BD_PAD; |
|
if (data){ |
//Copy the data into the transmit buffer, byte at a time |
char* data_p = (char*) data; |
char* data_b = (char*) tx_bd->addr; |
for(i=0;i<length;i++) |
{ |
data_b[i] = data_p[i]; |
} |
} |
|
/* Set the length of the packet's data in the buffer descriptor */ |
tx_bd->len_status = (tx_bd->len_status & 0x0000ffff) | |
((length&0xffff) << 16); |
|
/* Send it on its way. Tell controller its ready, interrupt when sent |
* and to put the CRC on the end. |
*/ |
tx_bd->len_status |= (OETH_TX_BD_READY | OETH_TX_BD_CRC | OETH_TX_BD_IRQ); |
|
next_tx_buf_num = (next_tx_buf_num + 1) & OETH_TXBD_NUM_MASK; |
|
return; |
|
} |
|
/* The interrupt handler. |
*/ |
void |
oeth_interrupt(void) |
{ |
|
volatile oeth_regs *regs; |
regs = (oeth_regs *)(OETH_REG_BASE); |
|
uint int_events; |
int serviced; |
|
serviced = 0; |
|
/* Get the interrupt events that caused us to be here. |
*/ |
int_events = regs->int_src; |
regs->int_src = int_events; |
|
|
/* Handle receive event in its own function. |
*/ |
if (int_events & (OETH_INT_RXF | OETH_INT_RXE)) { |
serviced |= 0x1; |
oeth_rx(); |
} |
|
/* Handle transmit event in its own function. |
*/ |
if (int_events & (OETH_INT_TXB | OETH_INT_TXE)) { |
serviced |= 0x2; |
oeth_tx(); |
serviced |= 0x2; |
|
} |
|
/* Check for receive busy, i.e. packets coming but no place to |
* put them. |
*/ |
if (int_events & OETH_INT_BUSY) { |
serviced |= 0x4; |
if (!(int_events & (OETH_INT_RXF | OETH_INT_RXE))) |
oeth_rx(); |
} |
|
return; |
} |
|
|
|
static void |
oeth_rx(void) |
{ |
volatile oeth_regs *regs; |
regs = (oeth_regs *)(OETH_REG_BASE); |
|
volatile oeth_bd *rx_bdp; |
int pkt_len, i; |
int bad = 0; |
|
rx_bdp = ((oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM; |
|
|
/* Find RX buffers marked as having received data */ |
for(i = 0; i < OETH_RXBD_NUM; i++) |
{ |
bad=0; |
if(!(rx_bdp[i].len_status & OETH_RX_BD_EMPTY)){ /* Looking for NOT empty buffers desc. */ |
/* Check status for errors. |
*/ |
if (rx_bdp[i].len_status & (OETH_RX_BD_TOOLONG | OETH_RX_BD_SHORT)) { |
bad = 1; |
report(0xbaad0001); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_DRIBBLE) { |
bad = 1; |
report(0xbaad0002); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_CRCERR) { |
bad = 1; |
report(0xbaad0003); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_OVERRUN) { |
bad = 1; |
report(0xbaad0004); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_MISS) { |
report(0xbaad0005); |
} |
if (rx_bdp[i].len_status & OETH_RX_BD_LATECOL) { |
bad = 1; |
report(0xbaad0006); |
} |
if (bad) { |
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS; |
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY; |
exit(0xbaaaaaad); |
|
continue; |
} |
else { |
/* Process the incoming frame. |
*/ |
pkt_len = rx_bdp[i].len_status >> 16; |
|
/* Do something here with the data - copy it into userspace, perhaps*/ |
|
/* finish up */ |
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS; /* Clear stats */ |
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY; /* Mark RX BD as empty */ |
rx_done++; |
} |
} |
} |
} |
|
|
|
static void |
oeth_tx(void) |
{ |
volatile oeth_bd *tx_bd; |
int i; |
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/ |
|
/* Go through the TX buffs, search for one that was just sent */ |
for(i = 0; i < OETH_TXBD_NUM; i++) |
{ |
/* Looking for buffer NOT ready for transmit. and IRQ enabled */ |
if( (!(tx_bd[i].len_status & (OETH_TX_BD_READY))) && (tx_bd[i].len_status & (OETH_TX_BD_IRQ)) ) |
{ |
/* Single threaded so no chance we have detected a buffer that has had its IRQ bit set but not its BD_READ flag. Maybe this won't work in linux */ |
tx_bd[i].len_status &= ~OETH_TX_BD_IRQ; |
|
/* Probably good to check for TX errors here */ |
|
/* set our test variable */ |
tx_done++; |
|
} |
} |
return; |
} |
|
// A function and defines to fill and transmit a packet |
#define MAX_TX_BUFFER 1532 |
static char tx_buffer[MAX_TX_BUFFER]; |
|
void |
fill_and_tx_packet(int size) |
{ |
int i; |
char tx_byte; |
|
volatile oeth_regs *regs; |
regs = (oeth_regs *)(OETH_REG_BASE); |
|
volatile oeth_bd *tx_bd; |
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; |
tx_bd = (struct oeth_bd*) &tx_bd[next_tx_buf_num]; |
|
// If it's in use - wait |
while ((tx_bd->len_status & OETH_TX_BD_IRQ)); |
|
// Use rand() function to generate data for transmission |
// Assumption: ethernet buffer descriptors are 4byte aligned |
char* data_b = (char*) tx_bd->addr; |
// We will fill with words until there' less than a word to go |
int words_to_fill = size/ sizeof(unsigned int); |
unsigned int* data_w = (unsigned int*) data_b; |
|
for(i=0;i<words_to_fill;i++) |
data_w[i] = rand(); |
|
// Point data_b to offset wher word fills ended |
data_b += (words_to_fill * sizeof(unsigned int)); |
|
int leftover_size = size - (words_to_fill * sizeof(unsigned int)); |
|
for(i=0;i<leftover_size;i++) |
{ |
data_b[i] = rand()&0xff; |
} |
|
tx_packet((void*)0, size); |
} |
|
int |
main () |
{ |
int i; |
|
/* Initialise handler vector */ |
int_init(); |
|
/* Install ethernet interrupt handler, it is enabled here too */ |
int_add(ETH0_IRQ, oeth_interrupt, 0); |
|
/* Enable interrupts in supervisor register */ |
cpu_enable_user_interrupts(); |
|
ethmac_setup(); /* Configure MAC, TX/RX BDs and enable RX and TX in MODER */ |
|
/* clear tx_done, the tx interrupt handler will set it when it's been transmitted */ |
tx_done = 0; |
rx_done = 0; |
|
ethphy_set_100mbit(0); |
|
#ifndef ETH_TX_TEST_LENGTH |
# define ETH_TX_START_LENGTH 40 |
# define ETH_TX_TEST_LENGTH 1024 |
# define ETH_TX_TEST_LENGTH_INCREMENT 21 |
//# define ETH_TX_TEST_LENGTH OETH_TX_BUFF_SIZE |
#endif |
|
for(i=ETH_TX_START_LENGTH;i<ETH_TX_TEST_LENGTH; |
i+=ETH_TX_TEST_LENGTH_INCREMENT) |
fill_and_tx_packet(i); |
|
ethphy_set_10mbit(0); |
|
for(i=ETH_TX_START_LENGTH;i<ETH_TX_TEST_LENGTH; |
i+=ETH_TX_TEST_LENGTH_INCREMENT) |
fill_and_tx_packet(i); |
|
exit(0x8000000d); |
|
|
} |
/s3adsp1800/sw/tests/ethmac/sim/Makefile
0,0 → 1,14
# Set the path to our board's root directory |
BOARD_SW_ROOT=../../.. |
|
include $(BOARD_SW_ROOT)/Makefile.inc |
|
%.dis: %.elf |
$(Q)$(OR32_OBJDUMP) -d $< > $@ |
|
%.bin: %.elf |
$(Q)$(OR32_OBJCOPY) -O binary $< $@ |
|
clean: |
$(Q)rm -f *.elf *.bin *.vmem *.flashin *.dis |
|
/s3adsp1800/sw/Makefile.inc
0,0 → 1,24
|
# Expecting BOARD_SW_ROOT already set to indicate how far below directory we're |
# in the board's software root path is. |
|
# Root from the board's sw/ path |
PROJ_ROOT=../../../.. |
|
# Figure out actual path the common software directory |
SW_ROOT=$(BOARD_SW_ROOT)/$(PROJ_ROOT)/sw |
|
# Set the BOARD_PATH to point to the root of this board build |
BOARD=xilinx/s3adsp1800 |
|
# Set RTL_VERILOG_INCLUDE_DIR so software |
RTL_VERILOG_INCLUDE_DIR=$(shell pwd)/$(BOARD_SW_ROOT)/../rtl/verilog/include |
|
# Set the processor capability flags |
MARCH_FLAGS =-mhard-mul -mhard-div -mhard-float |
#MARCH_FLAGS =-mhard-mul -msoft-div -msoft-float |
export MARCH_FLAGS |
|
# Finally include the main software include file |
|
include $(SW_ROOT)/Makefile.inc |
/s3adsp1800/sw/board/include/board.h
0,0 → 1,87
#ifndef _BOARD_H_ |
#define _BOARD_H_ |
|
#define IN_CLK 25000000 // Hz |
//#define IN_CLK 50000000 // Hz |
//#define IN_CLK 66666667 // Hz |
|
// |
// ROM bootloader |
// |
// Uncomment the appropriate bootloader define. This will effect the bootrom.S |
// file, which is compiled and converted into Verilog for inclusion at |
// synthesis time. See bootloader/bootloader.S for details on each option. |
#ifndef PRELOAD_RAM |
//#define BOOTROM_SPI_FLASH |
#define BOOTROM_GOTO_RESET |
//#define BOOTROM_LOOP_AT_ZERO |
//#define BOOTROM_LOOP_IN_ROM |
#else |
|
// For now just go to reset on board reset |
#define BOOTROM_GOTO_RESET |
|
#endif |
|
// Address bootloader should start from in FLASH |
// Last 256KB of 8MB flash - offset 0x7c0000 (8MB-256KB) |
#define BOOTROM_ADDR_BYTE2 0x7c |
#define BOOTROM_ADDR_BYTE1 0x00 |
#define BOOTROM_ADDR_BYTE0 0x00 |
// Causes SPI bootloader to loop if SPI didn't give correct size of image |
#define SPI_RETRY_IF_INSANE_SIZEWORD |
|
// |
// Defines for each core (memory map base, OR1200 interrupt line number, etc.) |
// |
#define SDRAM_BASE 0x0 |
|
#define GPIO_0_BASE 0x91000000 |
|
#define UART0_BASE 0x90000000 |
#define UART0_IRQ 2 |
#define UART0_BAUD_RATE 115200 |
|
|
#define SPI0_BASE 0xb0000000 |
#define SPI0_IRQ 6 |
|
#define I2C_0_BASE 0xa0000000 |
#define I2C_0_IRQ 10 |
|
#define ETH0_BASE 0x92000000 |
#define ETH0_IRQ 4 |
|
#define ETH_MACADDR0 0x00 |
#define ETH_MACADDR1 0x12 |
#define ETH_MACADDR2 0x34 |
#define ETH_MACADDR3 0x56 |
#define ETH_MACADDR4 0x78 |
#define ETH_MACADDR5 0x9a |
|
// |
// OR1200 tick timer period define |
// |
#define TICKS_PER_SEC 100 |
|
|
|
// |
// UART driver configuration |
// |
#define UART_NUM_CORES 1 |
#define UART_BASE_ADDRESSES_CSV UART0_BASE |
#define UART_BAUD_RATES_CSV UART0_BAUD_RATE |
|
|
// |
// i2c_master_slave core driver configuration |
// |
|
#define I2C_MASTER_SLAVE_NUM_CORES 1 |
|
#define I2C_MASTER_SLAVE_BASE_ADDRESSES_CSV \ |
I2C_0_BASE |
|
|
#endif |
/s3adsp1800/syn/xst/run/Makefile
0,0 → 1,2
include ../bin/Makefile |
|
/s3adsp1800/syn/xst/bin/Makefile
0,0 → 1,175
###################################################################### |
#### #### |
#### ORPSoC Xilinx Synthesis Makefile #### |
#### #### |
#### Author(s): #### |
#### - Julius Baxter, julius@opencores.org #### |
#### #### |
#### #### |
###################################################################### |
#### #### |
#### Copyright (C) 2009,2010,2011 Authors and 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 #### |
#### #### |
###################################################################### |
|
# Name of the directory we're currently in |
CUR_DIR=$(shell pwd) |
|
# We don't want the usbhostslave module to be pulled in during synthesis because |
# we haven't copied the headers to our RTL director |
#COMMON_VERILOG_MODULES_EXCLUDE+= usbhostslave |
|
|
# The root path of the board build |
BOARD_ROOT ?=$(CUR_DIR)/../../.. |
include $(BOARD_ROOT)/Makefile.inc |
|
RTL_TOP ?=$(DESIGN_NAME)_top |
|
SYN_RUN_DIR=$(BOARD_SYN_DIR)/run |
|
TIMESCALE_FILE=timescale.v |
SYNDIR_TIMESCALE_FILE=$(SYN_RUN_DIR)/$(TIMESCALE_FILE) |
$(SYNDIR_TIMESCALE_FILE): |
$(Q)echo "" > $@ |
|
SYN_VERILOG_DEFINES=synthesis-defines.v |
SYNDIR_SYN_VERILOG_DEFINES=$(SYN_RUN_DIR)/$(SYN_VERILOG_DEFINES) |
$(SYNDIR_SYN_VERILOG_DEFINES): |
$(Q)echo "\`define SYNTHESIS" > $@ |
$(Q)echo "\`define XILINX" >> $@ |
$(Q)echo "" >> $@ |
|
GENERATED_DEFINES = $(BOOTROM_VERILOG) |
GENERATED_DEFINES += $(SYNDIR_TIMESCALE_FILE) |
GENERATED_DEFINES += $(SYNDIR_SYN_VERILOG_DEFINES) |
|
FPGA_PART ?=xc3sd1800a-fg676-4 |
#xc5vlx50-ff676-1 |
OPT_MODE ?=Speed |
OPT_LEVEL ?=2 |
|
XILINX_FLAGS ?=-intstyle silent |
XILINX_XST_FLAGS ?= -power NO -glob_opt AllClockNets -write_timing_constraints NO -cross_clock_analysis NO -slice_utilization_ratio 100 -bram_utilization_ratio 100 -dsp_utilization_ratio 100 -safe_implementation No -fsm_style lut -ram_extract Yes -ram_style Auto -rom_extract Yes -rom_style Auto -auto_bram_packing NO -mux_extract YES -mux_style Auto -decoder_extract YES -priority_extract YES -shreg_extract YES -shift_extract YES -xor_collapse YES -resource_sharing YES -async_to_sync NO -use_dsp48 auto -iobuf YES -max_fanout 1000 -bufg 32 -register_duplication YES -equivalent_register_removal YES -register_balancing No -slice_packing YES -optimize_primitives NO -use_clock_enable Auto -use_sync_set Auto -use_sync_reset Auto -iob Auto -slice_utilization_ratio_maxmargin 5 #-keep_hierarchy YES |
|
XCF_FILE=$(DESIGN_NAME).xcf |
XST_FILE=$(DESIGN_NAME).xst |
PRJ_FILE=$(DESIGN_NAME).prj |
NGC_FILE=$(DESIGN_NAME).ngc |
NETLIST_FILE=$(DESIGN_NAME).v |
|
|
XST_PRJ_FILE_SRC_DECLARE=verilog work |
|
print-config: |
$(Q)echo; echo "\t### Synthesis make configuration ###"; echo |
$(Q)echo "\tFPGA_PART="$(FPGA_PART) |
$(Q)echo "\tOPT_MODE="$(OPT_MODE) |
$(Q)echo "\tOTP_LEVEL="$(OPT_LEVEL) |
$(Q)echo "\tXILINX_XST_FLAGS="$(XILINX_XST_FLAGS) |
$(Q)echo |
|
all: $(NGC_FILE) |
|
# Generate the .xst file |
# See this page for information on options: |
# http://www.xilinx.com/itp/xilinx4/data/docs/xst/command_line5.html |
$(XST_FILE): |
$(Q)echo; echo "\t#### Generating XST file ####"; echo |
$(Q)echo "# XST Script for ORPSoC Synthesis" > $@ |
$(Q)echo "# This file is autogenerated - any changes will be overwritten" >> $@ |
$(Q)echo "# See the Makefile in syn/xst/bin to make changes" >> $@ |
$(Q)echo "run" >> $@ |
$(Q)echo "-ifn "$(PRJ_FILE) >> $@ |
$(Q)echo "-ifmt mixed" >> $@ |
$(Q)echo "-top "$(RTL_TOP) >> $@ |
$(Q)echo "-ofmt NGC" >> $@ |
$(Q)echo "-ofn "$(NGC_FILE) >> $@ |
$(Q)echo "-p "$(FPGA_PART) >> $@ |
$(Q)echo "-opt_level "$(OPT_LEVEL) >> $@ |
$(Q)echo "-opt_mode "$(OPT_MODE) >> $@ |
$(Q)echo "-uc "$(XCF_FILE) >> $@ |
# $(Q)echo "elaborate " >> $@ |
# $(Q)echo -n "-vlgpath \"" >> $@ |
# option missing from XST - wtf?! $(Q)for vlogpath in $(VERILOG_SRC_PATHS); do \ |
echo -n $$vlogpath" "; done >> $@ |
# $(Q)echo "\"" >> $@ |
# Give board then common verilog include paths, hoping xst does a sensible thing |
# and searches them in order. |
$(Q)echo "-vlgincdir { "$(BOARD_RTL_VERILOG_INCLUDE_DIR)" "$(COMMON_RTL_VERILOG_DIR)/include" "$(BOOTROM_SW_DIR) " }" >> $@ |
$(Q)echo >> $@ |
|
# Generate Xilinx project (.prj) file |
$(PRJ_FILE): $(RTL_VERILOG_SRC) |
$(Q)echo; echo "\t#### Generating Xilinx PRJ file ####"; |
# $(Q)echo "# Autogenerated XST .prj file" > $@ |
# $(Q)echo "# Any changes will be written over." >> $@ |
$(Q)for file in $(RTL_VERILOG_SRC); do \ |
echo $(XST_PRJ_FILE_SRC_DECLARE) $$file >> $@ ; \ |
done |
$(Q)echo >> $@ |
$(Q)echo |
|
# Constraints file |
$(XCF_FILE): |
$(Q)echo; echo "\t#### Generating Xilinx XCF file ####"; echo |
$(Q)echo "# Autogenerated .xcf file" > $@ |
$(Q)echo "#" >> $@ |
$(Q)echo "# Not much here, XST is smart enough to determine clocks through DCMs" >> $@ |
$(Q)echo "#" >> $@ |
$(Q)echo "# 125MHz single-ended. XTAL used as main system clock" >> $@ |
$(Q)echo "Net sys_clk_i TNM_NET = sys_clk_i;" >> $@ |
$(Q)echo "TIMESPEC TS_sys_clk_i = PERIOD sys_clk_i 8000 ps; # 125MHz" >> $@ |
$(Q)echo "# Ignore the reset logic" >> $@ |
$(Q)echo "NET rst_n_pad_i* TIG;" >> $@ |
$(Q)echo "NET tck_pad_i TNM_NET = tck_pad_i;">> $@ |
$(Q)echo "TIMESPEC TS_tck_pad_i = PERIOD tck_pad_i 40 ns;" >> $@ |
|
|
# XST command |
$(NGC_FILE): $(PRJ_FILE) $(XST_FILE) $(XCF_FILE) $(GENERATED_DEFINES) |
$(Q)echo; echo "\t#### Running XST ####"; echo; |
$(Q)(. $(XILINX_SETTINGS_SCRIPT) ; xst -ifn $(XST_FILE) $(XILINX_FLAGS) $(XST_FLAGS) ) |
$(Q)echo |
|
netlist: $(NETLIST_FILE) |
|
# Netlist generation command |
$(NETLIST_FILE): $(NGC_FILE) |
$(Q)echo; echo "\t#### Generating verilog netlist ####"; echo; |
$(Q)(. $(XILINX_SETTINGS_SCRIPT) ; \ |
netgen -sim -aka -dir . -ofmt verilog $< -w $@ ) |
|
|
clean: |
$(Q)rm -rf *.* xst _xmsgs |
|
clean-sw: |
$(MAKE) -C $(PROJECT_ROOT)/sw/lib distclean |
|
distclean: clean-sw clean |
|
|
.PRECIOUS : $(NGC_FILE) $(XST_FILE) $(XCF_FILE) |
|
/s3adsp1800/README
0,0 → 1,5
Xilinx Spartan 3A DSP board build |
|
See the project's main documentation in doc/ for information on this build. |
|
|