1
0
mirror of git://projects.qi-hardware.com/nn-usb-fpga.git synced 2025-04-21 12:27:27 +03:00

Fixing some examples, adding scripts for compiling xilinx libs with ghdl

This commit is contained in:
Carlos Camargo
2010-08-31 09:39:37 -05:00
parent b6f32d536f
commit acf516e22d
53 changed files with 13780 additions and 175 deletions

View File

@@ -0,0 +1,97 @@
DESIGN = sram_bus
PINS = sram_bus.ucf
DEVICE = xc3s500e-VQ100-4
BGFLAGS = -g TdoPin:PULLNONE -g DonePin:PULLUP \
-g CRC:enable -g StartUpClk:CCLK
SIM_CMD = /opt/cad/modeltech/bin/vsim
SIM_COMP_SCRIPT = simulation/$(DESIGN)_TB.do
SIMGEN_OPTIONS = -p $(FPGA_ARCH) -lang $(LANGUAGE)
SAKC_IP = 192.168.254.101
IVERILOG = iverilog
XILINXCADROOT = /opt/cad/Xilinx/verilog/src
#XILINXCADROOT = /opt/cad/modeltech/xilinx/verilog/
SRC = sram_bus.v
SIM_SRC = $(DESIGN)_TB.v \
# sim/unisims/BUFG.v \
# sim/unisims/DCM.v \
# sim/unisims/FDDRRSE.v \
# glbl.v
# sim/unisims/RAMB16_S2_S9.v
all: bits
remake: clean-build all
clean:
rm -f *~ */*~ a.out *.log *.key *.edf *.ps trace.dat
rm -rf *.bit
clean-build: clean
rm -rf build
cleanall: clean
rm -rf build $(DESIGN).bit
bits: $(DESIGN).bit
#
# Synthesis
#
build/project.src:
@[ -d build ] || mkdir build
@rm -f $@
for i in $(SRC); do echo verilog work ../$$i >> $@; done
for i in $(SRC_HDL); do echo VHDL work ../$$i >> $@; done
build/project.xst: build/project.src
echo "run" > $@
echo "-top $(DESIGN) " >> $@
echo "-p $(DEVICE)" >> $@
echo "-opt_mode Area" >> $@
echo "-opt_level 1" >> $@
echo "-ifn project.src" >> $@
echo "-ifmt mixed" >> $@
echo "-ofn project.ngc" >> $@
echo "-ofmt NGC" >> $@
echo "-rtlview yes" >> $@
build/project.ngc: build/project.xst $(SRC)
cd build && xst -ifn project.xst -ofn project.log
build/project.ngd: build/project.ngc $(PINS)
cd build && ngdbuild -p $(DEVICE) project.ngc -uc ../$(PINS)
build/project.ncd: build/project.ngd
cd build && map -pr b -p $(DEVICE) project
build/project_r.ncd: build/project.ncd
cd build && par -w project project_r.ncd
build/project_r.twr: build/project_r.ncd
cd build && trce -v 25 project_r.ncd project.pcf
$(DESIGN).bit: build/project_r.ncd build/project_r.twr
cd build && bitgen project_r.ncd -l -w $(BGFLAGS)
@mv -f build/project_r.bit $@
build/project_r.v: build/project_r.ncd
cd build && ngd2ver project.ngd -w project.v
modelsim:
cd simulation; $(SIM_CMD) -do $(DESIGN)_TB.do
timesim: build/project_r.v
cd simulation; $(SIM_CMD) -do $(DESIGN)_TIMING_TB.do
iversim:
$(IVERILOG) -Wall -o simulation/$(DESIGN)_TB.vvp $(VINCDIR) $(SRC) $(SIM_SRC) -s $(DESIGN)_TB
vvp simulation/$(DESIGN)_TB.vvp; mv $(DESIGN)_TB.vcd simulation/
gtkwave simulation/$(DESIGN)_TB.vcd&
upload: $(DESIGN).bit
scp $(DESIGN).bit root@$(SAKC_IP):

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,63 @@
/****************************************************************************************
*
* 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.
*
****************************************************************************************/
// Timing parameters based on Speed Grade
// SYMBOL UNITS DESCRIPTION
// ------ ----- -----------
// `ifdef sg6T // Timing Parameters for -6T (CL = 2.5)
parameter tCK = 6.0; // tCK ns Nominal Clock Cycle Time
parameter tDQSQ = 0.45; // tDQSS ns DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter tMRD = 12.0; // tMRD ns Load Mode Register command cycle time
parameter tRAP = 15.0; // tRAP ns ACTIVE to READ with Auto precharge command
parameter tRAS = 42.0; // tRAS ns Active to Precharge command time
parameter tRC = 60.0; // tRC ns Active to Active/Auto Refresh command time
parameter tRFC = 120.0; // tRFC ns Refresh to Refresh Command interval time
parameter tRCD = 15.0; // tRCD ns Active to Read/Write command time
parameter tRP = 15.0; // tRP ns Precharge command period
parameter tRRD = 12.0; // tRRD ns Active bank a to Active bank b command time
parameter tWR = 15.0; // tWR ns Write recovery time
// Size Parameters based on Part Width
//`else `define x16
parameter ADDR_BITS = 13; // Set this parameter to control how many Address bits are used
parameter DQ_BITS = 16; // Set this parameter to control how many Data bits are used
parameter DQS_BITS = 2; // Set this parameter to control how many DQS bits are used
parameter DM_BITS = 2; // Set this parameter to control how many DM bits are used
parameter COL_BITS = 10; // Set this parameter to control how many Column bits are used
parameter full_mem_bits = 2+ADDR_BITS+COL_BITS; // Set this parameter to control how many unique addresses are used
parameter part_mem_bits = 14; // Set this parameter to control how many unique addresses are used
parameter no_halt = 0; // If set to 1, the model won't halt on command sequence/major errors
parameter Debug = 1; // Turn on debug message

View File

@@ -0,0 +1,64 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2005 Xilinx, Inc.
// This design is confidential and proprietary of Xilinx, All Rights Reserved.
///////////////////////////////////////////////////////////////////////////////
// ____ ____
// / /\/ /
// /___/ \ / Vendor : Xilinx
// \ \ \/ Version : $Name: mig_v1_73_b0 $
// \ \ Application : MIG
// / / Filename : mem_interface_top_parameters_0.v
// /___/ /\ Date Last Modified : $Date: 2007/06/06 05:44:42 $
// \ \ / \ Date Created : Mon May 2 2005
// \___\/\___\
// Device : Spartan-3/3E/3A
// Design Name : DDR1 SDRAM
// Purpose : This module has the parameters used in the design.
///////////////////////////////////////////////////////////////////////////////
`define data_width 16
`define data_strobe_width 2
`define data_mask_width 2
`define clk_width 1
`define fifo_16 1
`define ReadEnable 1
`define memory_width 8
`define DatabitsPerReadClock 8
`define DatabitsPerMask 8
`define no_of_cs 1
`define data_mask 1
`define mask_disable 0
`define RESET 0
`define cke_width 1
`define registered 0
`define col_ap_width 11
`define write_pipe_itr 1
`define write_pipeline 4
`define top_bottom 0
`define left_right 1
`define row_address 13
`define column_address 10
`define bank_address 2
`define spartan3e 1
`define burst_length 3'b001
`define burst_type 1'b0
`define cas_latency_value 3'b110
`define Operating_mode 5'b00000
`define load_mode_register 13'b0000001100001
`define drive_strengh 1'b0
`define dll_enable 1'b0
`define ext_load_mode_register 13'b0000000000000
`define chip_address 1
`define reset_active_low 1'b1
`define rcd_count_value 3'b001
`define ras_count_value 4'b0101
`define mrd_count_value 1'b0
`define rp_count_value 3'b001
`define rfc_count_value 6'b001001
`define twr_count_value 3'b110
`define twtr_count_value 3'b100
`define max_ref_width 11
`define max_ref_cnt 11'b10000000001
`timescale 1ns/100ps

View File

@@ -0,0 +1,44 @@
********************************************************************************************
The sim folder has sample test_bench files to simulate the designs in Modelsim environment.
This folder has the memory model, test bench, glbl file and required parameter files.
Read the steps in this file before simulations are done.
To run simulations for this sample configuration, user has to generate the RTL from the tool for the following GUI
options.
Data_width : 64
HDL : Verilog or VHDL
Memory configuration : x16
DIMM/Component : Component
Memory Part No : MT46V16M16XX-5
Add test bench : Yes
Use DCM : Yes
Number of controllers : 1
Number of Write pipelines : 4
-----------------------------------------------For Verilog or VHDL----------------------------------------------------------
1. After the rtl is generated, create the Model sim project file. Add all the rtl files from the rtl folder
to the project Also add the memory model, test bench and glbl files from the sim folder.
2. Compile the design.
3. After successful compilation of design load the design using the following comamnd.
vsim -t ps +notimingchecks -L ../Modeltech_6.1a/unisims_ver work.ddr1_test_tb glbl
Note : User should set proper path for unisim verilog libraries
4. After the design is successfully loaded, run the simulations and view the waveforms.
Notes :
1. To run simulations for different data widths and configurations, users should modify the test bench files
with right memory models and design files.
2. User must manually change the frequency of the test bench for proper simulations.
3. Users should modify the test bench files for without test bench case.

View File

@@ -0,0 +1,52 @@
//---------------------------------------------------------------------------
// Behavioral model of a static ram chip
//
// Organization:
//
// 16 bit x 2**(adr_width-1)
//---------------------------------------------------------------------------
module sram16 #(
parameter adr_width = 18
) (
input [adr_width-1:0] adr,
inout [15:0] dat,
input ub_n,
input lb_n,
input cs_n,
input we_n,
input oe_n
);
parameter dat_width = 16;
//---------------------------------------------------------------------------
// Actual RAM cells
//---------------------------------------------------------------------------
reg [7:0] mem_ub [0:1<<adr_width];
reg [7:0] mem_lb [0:1<<adr_width];
//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------
wire [15:0] mem = { mem_ub[adr], mem_lb[adr] };
wire [15:0] zzz = 16'bz;
// Drive output
assign dat = (!cs_n && !oe_n) ? mem : zzz;
// Write to UB
always @(*)
if (!cs_n && !we_n && !ub_n)
mem_ub[adr] = dat[15:8];
// Write to LB
always @(*)
if (!cs_n && !we_n && !lb_n)
mem_lb[adr] = dat[7:0];
always @(*)
if (!we_n && !oe_n)
$display("Operational error in RamChip: OE and WE both active");
endmodule

View File

@@ -0,0 +1,33 @@
// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/BUFG.v,v 1.5.158.1 2007/03/09 18:13:02 patrickp Exp $
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1995/2004 Xilinx, Inc.
// All Right Reserved.
///////////////////////////////////////////////////////////////////////////////
// ____ ____
// / /\/ /
// /___/ \ / Vendor : Xilinx
// \ \ \/ Version : 8.1i (I.13)
// \ \ Description : Xilinx Functional Simulation Library Component
// / / Global Clock Buffer
// /___/ /\ Filename : BUFG.v
// \ \ / \ Timestamp : Thu Mar 25 16:42:14 PST 2004
// \___\/\___\
//
// Revision:
// 03/23/04 - Initial version.
// End Revision
`timescale 100 ps / 10 ps
module BUFG (O, I);
output O;
input I;
buf B1 (O, I);
endmodule

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,102 @@
// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/FDDRRSE.v,v 1.15.48.1 2007/03/09 18:13:02 patrickp Exp $
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1995/2004 Xilinx, Inc.
// All Right Reserved.
///////////////////////////////////////////////////////////////////////////////
// ____ ____
// / /\/ /
// /___/ \ / Vendor : Xilinx
// \ \ \/ Version : 8.1i (I.27)
// \ \ Description : Xilinx Functional Simulation Library Component
// / / Dual Data Rate D Flip-Flop with Synchronous Reset and Set and Clock Enable
// /___/ /\ Filename : FDDRRSE.v
// \ \ / \ Timestamp : Thu Mar 25 16:42:16 PST 2004
// \___\/\___\
//
// Revision:
// 03/23/04 - Initial version.
// 02/04/05 - Rev 0.0.1 Remove input/output bufs; Seperate GSR from clock block.
// 05/06/05 - Remove internal input data strobe and add to the output. (CR207678)
// 10/20/05 - Add set & reset check to main block. (CR219794)
// 10/28/05 - combine strobe block and data block. (CR220298).
// 2/07/06 - Remove set & reset from main block and add specify block (CR225119)
// 2/10/06 - Change Q from reg to wire (CR 225613)
// End Revision
`timescale 1 ps / 1 ps
module FDDRRSE (Q, C0, C1, CE, D0, D1, R, S);
parameter INIT = 1'h0;
output Q;
input C0, C1, CE, D0, D1, R, S;
wire Q;
reg q_out;
reg q0_out, q1_out;
reg C0_tmp, C1_tmp;
initial begin
q_out = INIT;
q0_out = INIT;
q1_out = INIT;
C0_tmp = 0;
C1_tmp = 0;
end
assign Q = q_out;
always @(posedge C0)
if (CE == 1 || R == 1 || S == 1) begin
C0_tmp <= 1;
C0_tmp <= #100 0;
end
always @(posedge C1)
if (CE == 1 || R == 1 || S == 1) begin
C1_tmp <= 1;
C1_tmp <= #100 0;
end
always @(posedge C0)
if (R)
q0_out <= 0;
else if (S)
q0_out <= 1;
else if (CE)
q0_out <= D0;
always @(posedge C1)
if (R)
q1_out <= 0;
else if (S)
q1_out <= 1;
else if (CE)
q1_out <= D1;
always @(posedge C0_tmp or posedge C1_tmp )
if (C1_tmp)
q_out = q1_out;
else
q_out = q0_out;
specify
if (R)
(posedge C0 => (Q +: 1'b0)) = (100, 100);
if (!R && S)
(posedge C0 => (Q +: 1'b1)) = (100, 100);
if (!R && !S && CE)
(posedge C0 => (Q +: D0)) = (100, 100);
if (R)
(posedge C1 => (Q +: 1'b0)) = (100, 100);
if (!R && S)
(posedge C1 => (Q +: 1'b1)) = (100, 100);
if (!R && !S && CE)
(posedge C1 => (Q +: D1)) = (100, 100);
endspecify
endmodule

View File

@@ -0,0 +1,521 @@
// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/RAMB16_S2.v,v 1.7.158.1 2007/03/09 18:13:18 patrickp Exp $
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1995/2005 Xilinx, Inc.
// All Right Reserved.
///////////////////////////////////////////////////////////////////////////////
// ____ ____
// / /\/ /
// /___/ \ / Vendor : Xilinx
// \ \ \/ Version : 8.1i (I.13)
// \ \ Description : Xilinx Functional Simulation Library Component
// / / 16K-Bit Data and 2K-Bit Parity Single Port Block RAM
// /___/ /\ Filename : RAMB16_S2.v
// \ \ / \ Timestamp : Thu Mar 10 16:43:35 PST 2005
// \___\/\___\
//
// Revision:
// 03/23/04 - Initial version.
// End Revision
`ifdef legacy_model
`timescale 1 ps / 1 ps
module RAMB16_S2 (DO, ADDR, CLK, DI, EN, SSR, WE);
parameter INIT = 2'h0;
parameter SRVAL = 2'h0;
parameter WRITE_MODE = "WRITE_FIRST";
parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
output [1:0] DO;
reg do0_out, do1_out;
input [12:0] ADDR;
input [1:0] DI;
input EN, CLK, WE, SSR;
reg [18431:0] mem;
reg [8:0] count;
reg [1:0] wr_mode;
wire [12:0] addr_int;
wire [1:0] di_int;
wire en_int, clk_int, we_int, ssr_int;
tri0 GSR = glbl.GSR;
always @(GSR)
if (GSR) begin
assign do0_out = INIT[0];
assign do1_out = INIT[1];
end
else begin
deassign do0_out;
deassign do1_out;
end
buf b_do_out0 (DO[0], do0_out);
buf b_do_out1 (DO[1], do1_out);
buf b_addr_0 (addr_int[0], ADDR[0]);
buf b_addr_1 (addr_int[1], ADDR[1]);
buf b_addr_2 (addr_int[2], ADDR[2]);
buf b_addr_3 (addr_int[3], ADDR[3]);
buf b_addr_4 (addr_int[4], ADDR[4]);
buf b_addr_5 (addr_int[5], ADDR[5]);
buf b_addr_6 (addr_int[6], ADDR[6]);
buf b_addr_7 (addr_int[7], ADDR[7]);
buf b_addr_8 (addr_int[8], ADDR[8]);
buf b_addr_9 (addr_int[9], ADDR[9]);
buf b_addr_10 (addr_int[10], ADDR[10]);
buf b_addr_11 (addr_int[11], ADDR[11]);
buf b_addr_12 (addr_int[12], ADDR[12]);
buf b_di_0 (di_int[0], DI[0]);
buf b_di_1 (di_int[1], DI[1]);
buf b_en (en_int, EN);
buf b_clk (clk_int, CLK);
buf b_we (we_int, WE);
buf b_ssr (ssr_int, SSR);
initial begin
for (count = 0; count < 256; count = count + 1) begin
mem[count] <= INIT_00[count];
mem[256 * 1 + count] <= INIT_01[count];
mem[256 * 2 + count] <= INIT_02[count];
mem[256 * 3 + count] <= INIT_03[count];
mem[256 * 4 + count] <= INIT_04[count];
mem[256 * 5 + count] <= INIT_05[count];
mem[256 * 6 + count] <= INIT_06[count];
mem[256 * 7 + count] <= INIT_07[count];
mem[256 * 8 + count] <= INIT_08[count];
mem[256 * 9 + count] <= INIT_09[count];
mem[256 * 10 + count] <= INIT_0A[count];
mem[256 * 11 + count] <= INIT_0B[count];
mem[256 * 12 + count] <= INIT_0C[count];
mem[256 * 13 + count] <= INIT_0D[count];
mem[256 * 14 + count] <= INIT_0E[count];
mem[256 * 15 + count] <= INIT_0F[count];
mem[256 * 16 + count] <= INIT_10[count];
mem[256 * 17 + count] <= INIT_11[count];
mem[256 * 18 + count] <= INIT_12[count];
mem[256 * 19 + count] <= INIT_13[count];
mem[256 * 20 + count] <= INIT_14[count];
mem[256 * 21 + count] <= INIT_15[count];
mem[256 * 22 + count] <= INIT_16[count];
mem[256 * 23 + count] <= INIT_17[count];
mem[256 * 24 + count] <= INIT_18[count];
mem[256 * 25 + count] <= INIT_19[count];
mem[256 * 26 + count] <= INIT_1A[count];
mem[256 * 27 + count] <= INIT_1B[count];
mem[256 * 28 + count] <= INIT_1C[count];
mem[256 * 29 + count] <= INIT_1D[count];
mem[256 * 30 + count] <= INIT_1E[count];
mem[256 * 31 + count] <= INIT_1F[count];
mem[256 * 32 + count] <= INIT_20[count];
mem[256 * 33 + count] <= INIT_21[count];
mem[256 * 34 + count] <= INIT_22[count];
mem[256 * 35 + count] <= INIT_23[count];
mem[256 * 36 + count] <= INIT_24[count];
mem[256 * 37 + count] <= INIT_25[count];
mem[256 * 38 + count] <= INIT_26[count];
mem[256 * 39 + count] <= INIT_27[count];
mem[256 * 40 + count] <= INIT_28[count];
mem[256 * 41 + count] <= INIT_29[count];
mem[256 * 42 + count] <= INIT_2A[count];
mem[256 * 43 + count] <= INIT_2B[count];
mem[256 * 44 + count] <= INIT_2C[count];
mem[256 * 45 + count] <= INIT_2D[count];
mem[256 * 46 + count] <= INIT_2E[count];
mem[256 * 47 + count] <= INIT_2F[count];
mem[256 * 48 + count] <= INIT_30[count];
mem[256 * 49 + count] <= INIT_31[count];
mem[256 * 50 + count] <= INIT_32[count];
mem[256 * 51 + count] <= INIT_33[count];
mem[256 * 52 + count] <= INIT_34[count];
mem[256 * 53 + count] <= INIT_35[count];
mem[256 * 54 + count] <= INIT_36[count];
mem[256 * 55 + count] <= INIT_37[count];
mem[256 * 56 + count] <= INIT_38[count];
mem[256 * 57 + count] <= INIT_39[count];
mem[256 * 58 + count] <= INIT_3A[count];
mem[256 * 59 + count] <= INIT_3B[count];
mem[256 * 60 + count] <= INIT_3C[count];
mem[256 * 61 + count] <= INIT_3D[count];
mem[256 * 62 + count] <= INIT_3E[count];
mem[256 * 63 + count] <= INIT_3F[count];
end
end
initial begin
case (WRITE_MODE)
"WRITE_FIRST" : wr_mode <= 2'b00;
"READ_FIRST" : wr_mode <= 2'b01;
"NO_CHANGE" : wr_mode <= 2'b10;
default : begin
$display("Attribute Syntax Error : The attribute WRITE_MODE on RAMB16_S2 instance %m is set to %s. Legal values for this attribute are WRITE_FIRST, READ_FIRST or NO_CHANGE.", WRITE_MODE);
$finish;
end
endcase
end
always @(posedge clk_int) begin
if (en_int == 1'b1) begin
if (ssr_int == 1'b1) begin
do0_out <= SRVAL[0];
do1_out <= SRVAL[1];
end
else begin
if (we_int == 1'b1) begin
if (wr_mode == 2'b00) begin
do0_out <= di_int[0];
do1_out <= di_int[1];
end
else if (wr_mode == 2'b01) begin
do0_out <= mem[addr_int * 2 + 0];
do1_out <= mem[addr_int * 2 + 1];
end
else begin
do0_out <= do0_out;
do1_out <= do1_out;
end
end
else begin
do0_out <= mem[addr_int * 2 + 0];
do1_out <= mem[addr_int * 2 + 1];
end
end
end
end
always @(posedge clk_int) begin
if (en_int == 1'b1 && we_int == 1'b1) begin
mem[addr_int * 2 + 0] <= di_int[0];
mem[addr_int * 2 + 1] <= di_int[1];
end
end
specify
(CLK *> DO) = (100, 100);
endspecify
endmodule
`else
// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/RAMB16_S2.v,v 1.7.158.1 2007/03/09 18:13:18 patrickp Exp $
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1995/2005 Xilinx, Inc.
// All Right Reserved.
///////////////////////////////////////////////////////////////////////////////
// ____ ____
// / /\/ /
// /___/ \ / Vendor : Xilinx
// \ \ \/ Version : 8.1i (I.13)
// \ \ Description : Xilinx Timing Simulation Library Component
// / / 16K-Bit Data and 2K-Bit Parity Single Port Block RAM
// /___/ /\ Filename : RAMB16_S2.v
// \ \ / \ Timestamp : Thu Mar 10 16:44:01 PST 2005
// \___\/\___\
//
// Revision:
// 03/23/04 - Initial version.
// 03/10/05 - Initialized outputs.
// End Revision
`timescale 1 ps/1 ps
module RAMB16_S2 (DO, ADDR, CLK, DI, EN, SSR, WE);
parameter INIT = 2'h0;
parameter SRVAL = 2'h0;
parameter WRITE_MODE = "WRITE_FIRST";
parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
output [1:0] DO;
input [12:0] ADDR;
input [1:0] DI;
input EN, CLK, WE, SSR;
reg [1:0] do_out = INIT[1:0];
reg [1:0] mem [8191:0];
reg [8:0] count, countp;
reg [1:0] wr_mode;
wire [12:0] addr_int;
wire [1:0] di_int;
wire en_int, clk_int, we_int, ssr_int;
wire di_enable = en_int && we_int;
tri0 GSR = glbl.GSR;
wire gsr_int;
buf b_gsr (gsr_int, GSR);
buf b_do [1:0] (DO, do_out);
buf b_addr [12:0] (addr_int, ADDR);
buf b_di [1:0] (di_int, DI);
buf b_en (en_int, EN);
buf b_clk (clk_int, CLK);
buf b_ssr (ssr_int, SSR);
buf b_we (we_int, WE);
always @(gsr_int)
if (gsr_int) begin
assign {do_out} = INIT;
end
else begin
deassign do_out;
end
initial begin
for (count = 0; count < 128; count = count + 1) begin
mem[count] = INIT_00[(count * 2) +: 2];
mem[128 * 1 + count] = INIT_01[(count * 2) +: 2];
mem[128 * 2 + count] = INIT_02[(count * 2) +: 2];
mem[128 * 3 + count] = INIT_03[(count * 2) +: 2];
mem[128 * 4 + count] = INIT_04[(count * 2) +: 2];
mem[128 * 5 + count] = INIT_05[(count * 2) +: 2];
mem[128 * 6 + count] = INIT_06[(count * 2) +: 2];
mem[128 * 7 + count] = INIT_07[(count * 2) +: 2];
mem[128 * 8 + count] = INIT_08[(count * 2) +: 2];
mem[128 * 9 + count] = INIT_09[(count * 2) +: 2];
mem[128 * 10 + count] = INIT_0A[(count * 2) +: 2];
mem[128 * 11 + count] = INIT_0B[(count * 2) +: 2];
mem[128 * 12 + count] = INIT_0C[(count * 2) +: 2];
mem[128 * 13 + count] = INIT_0D[(count * 2) +: 2];
mem[128 * 14 + count] = INIT_0E[(count * 2) +: 2];
mem[128 * 15 + count] = INIT_0F[(count * 2) +: 2];
mem[128 * 16 + count] = INIT_10[(count * 2) +: 2];
mem[128 * 17 + count] = INIT_11[(count * 2) +: 2];
mem[128 * 18 + count] = INIT_12[(count * 2) +: 2];
mem[128 * 19 + count] = INIT_13[(count * 2) +: 2];
mem[128 * 20 + count] = INIT_14[(count * 2) +: 2];
mem[128 * 21 + count] = INIT_15[(count * 2) +: 2];
mem[128 * 22 + count] = INIT_16[(count * 2) +: 2];
mem[128 * 23 + count] = INIT_17[(count * 2) +: 2];
mem[128 * 24 + count] = INIT_18[(count * 2) +: 2];
mem[128 * 25 + count] = INIT_19[(count * 2) +: 2];
mem[128 * 26 + count] = INIT_1A[(count * 2) +: 2];
mem[128 * 27 + count] = INIT_1B[(count * 2) +: 2];
mem[128 * 28 + count] = INIT_1C[(count * 2) +: 2];
mem[128 * 29 + count] = INIT_1D[(count * 2) +: 2];
mem[128 * 30 + count] = INIT_1E[(count * 2) +: 2];
mem[128 * 31 + count] = INIT_1F[(count * 2) +: 2];
mem[128 * 32 + count] = INIT_20[(count * 2) +: 2];
mem[128 * 33 + count] = INIT_21[(count * 2) +: 2];
mem[128 * 34 + count] = INIT_22[(count * 2) +: 2];
mem[128 * 35 + count] = INIT_23[(count * 2) +: 2];
mem[128 * 36 + count] = INIT_24[(count * 2) +: 2];
mem[128 * 37 + count] = INIT_25[(count * 2) +: 2];
mem[128 * 38 + count] = INIT_26[(count * 2) +: 2];
mem[128 * 39 + count] = INIT_27[(count * 2) +: 2];
mem[128 * 40 + count] = INIT_28[(count * 2) +: 2];
mem[128 * 41 + count] = INIT_29[(count * 2) +: 2];
mem[128 * 42 + count] = INIT_2A[(count * 2) +: 2];
mem[128 * 43 + count] = INIT_2B[(count * 2) +: 2];
mem[128 * 44 + count] = INIT_2C[(count * 2) +: 2];
mem[128 * 45 + count] = INIT_2D[(count * 2) +: 2];
mem[128 * 46 + count] = INIT_2E[(count * 2) +: 2];
mem[128 * 47 + count] = INIT_2F[(count * 2) +: 2];
mem[128 * 48 + count] = INIT_30[(count * 2) +: 2];
mem[128 * 49 + count] = INIT_31[(count * 2) +: 2];
mem[128 * 50 + count] = INIT_32[(count * 2) +: 2];
mem[128 * 51 + count] = INIT_33[(count * 2) +: 2];
mem[128 * 52 + count] = INIT_34[(count * 2) +: 2];
mem[128 * 53 + count] = INIT_35[(count * 2) +: 2];
mem[128 * 54 + count] = INIT_36[(count * 2) +: 2];
mem[128 * 55 + count] = INIT_37[(count * 2) +: 2];
mem[128 * 56 + count] = INIT_38[(count * 2) +: 2];
mem[128 * 57 + count] = INIT_39[(count * 2) +: 2];
mem[128 * 58 + count] = INIT_3A[(count * 2) +: 2];
mem[128 * 59 + count] = INIT_3B[(count * 2) +: 2];
mem[128 * 60 + count] = INIT_3C[(count * 2) +: 2];
mem[128 * 61 + count] = INIT_3D[(count * 2) +: 2];
mem[128 * 62 + count] = INIT_3E[(count * 2) +: 2];
mem[128 * 63 + count] = INIT_3F[(count * 2) +: 2];
end
end // initial begin
initial begin
case (WRITE_MODE)
"WRITE_FIRST" : wr_mode <= 2'b00;
"READ_FIRST" : wr_mode <= 2'b01;
"NO_CHANGE" : wr_mode <= 2'b10;
default : begin
$display("Attribute Syntax Error : The Attribute WRITE_MODE on RAMB16_S2 instance %m is set to %s. Legal values for this attribute are WRITE_FIRST, READ_FIRST or NO_CHANGE.", WRITE_MODE);
$finish;
end
endcase
end
always @(posedge clk_int) begin
if (en_int == 1'b1) begin
if (ssr_int == 1'b1) begin
{do_out} <= #100 SRVAL;
end
else begin
if (we_int == 1'b1) begin
if (wr_mode == 2'b00) begin
do_out <= #100 di_int;
end
else if (wr_mode == 2'b01) begin
do_out <= #100 mem[addr_int];
end
end
else begin
do_out <= #100 mem[addr_int];
end
end
// memory
if (we_int == 1'b1) begin
mem[addr_int] <= di_int;
end
end
end
endmodule
`endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,58 @@
// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/glbl.v,v 1.11.156.1 2007/03/09 18:12:55 patrickp Exp $
`timescale 1 ps / 1 ps
module glbl ();
parameter ROC_WIDTH = 100000;
parameter TOC_WIDTH = 0;
wire GSR;
wire GTS;
wire PRLD;
reg GSR_int;
reg GTS_int;
reg PRLD_int;
//-------- JTAG Globals --------------
wire JTAG_TDO_GLBL;
wire JTAG_TCK_GLBL;
wire JTAG_TDI_GLBL;
wire JTAG_TMS_GLBL;
wire JTAG_TRST_GLBL;
reg JTAG_CAPTURE_GLBL;
reg JTAG_RESET_GLBL;
reg JTAG_SHIFT_GLBL;
reg JTAG_UPDATE_GLBL;
reg JTAG_SEL1_GLBL = 0;
reg JTAG_SEL2_GLBL = 0 ;
reg JTAG_SEL3_GLBL = 0;
reg JTAG_SEL4_GLBL = 0;
reg JTAG_USER_TDO1_GLBL = 1'bz;
reg JTAG_USER_TDO2_GLBL = 1'bz;
reg JTAG_USER_TDO3_GLBL = 1'bz;
reg JTAG_USER_TDO4_GLBL = 1'bz;
assign (weak1, weak0) GSR = GSR_int;
assign (weak1, weak0) GTS = GTS_int;
assign (weak1, weak0) PRLD = PRLD_int;
initial begin
GSR_int = 1'b1;
PRLD_int = 1'b1;
#(ROC_WIDTH)
GSR_int = 1'b0;
PRLD_int = 1'b0;
end
initial begin
GTS_int = 1'b1;
#(TOC_WIDTH)
GTS_int = 1'b0;
end
endmodule

View File

@@ -0,0 +1,12 @@
vlib work
vlog -incr +libext+.v \
"../sram_bus.v" \
"../sram_bus_TB.v" \
"glbl.v"
vsim -t 1ps -L simprims_ver -L unisims_ver -L xilinxcorelib_ver sram_bus_TB glbl
view wave
#do wave.do
add wave *
view structure
view signals
run 5us

View File

@@ -0,0 +1,9 @@
vlib work
vlog -incr "../build/project.v" "../sram_bus_TB.v" "glbl.v"
vsim -t 1ps -L simprims_ver -L unisims_ver -L xilinxcorelib_ver sram_bus_TB glbl
view wave
#do wave.do
add wave *
view structure
view signals
run 5us

View File

@@ -0,0 +1,34 @@
# // ModelSim SE 6.0d Apr 25 2005 Linux 2.6.32-22-generic
# //
# // Copyright Mentor Graphics Corporation 2005
# // All Rights Reserved.
# //
# // THIS WORK CONTAINS TRADE SECRET AND
# // PROPRIETARY INFORMATION WHICH IS THE PROPERTY
# // OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS
# // AND IS SUBJECT TO LICENSE TERMS.
# //
# do sram_bus_TB.do
# ** Warning: (vlib-34) Library already exists at "work".
# Model Technology ModelSim SE vlog 6.0d Compiler 2005.04 Apr 25 2005
# -- Compiling module sram_bus
# -- Compiling module sram_bus_TB
# -- Compiling module glbl
#
# Top level modules:
# sram_bus_TB
# glbl
# vsim -L simprims_ver -L unisims_ver -L xilinxcorelib_ver -t 1ps sram_bus_TB glbl
# Loading work.sram_bus_TB
# Loading work.sram_bus
# Loading /opt/cad/modeltech/xilinx/verilog/unisims_ver.RAMB16_S2
# Loading work.glbl
# ** Warning: (vsim-3017) ../sram_bus_TB.v(21): [TFMPC] - Too few port connections. Expected 8, found 7.
# Region: /sram_bus_TB/uut
# ** Warning: (vsim-3015) ../sram_bus_TB.v(21): [PCDPC] - Port size (8 or 8) does not match connection size (1) for port 'sram_data'.
# Region: /sram_bus_TB/uut
# ** Warning: (vsim-3722) ../sram_bus_TB.v(21): [TFMPC] - Missing connection for port 'led'.
# .main_pane.mdi.interior.cs.vm.paneset.cli_0.wf.clip.cs
# .main_pane.workspace
# .main_pane.signals.interior.cs
quit

Binary file not shown.

View File

@@ -0,0 +1,29 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -format Logic -radix hexadecimal /sram_bus_TB_v/clk
add wave -noupdate -format Literal -radix hexadecimal /sram_bus_TB_v/addr
add wave -noupdate -format Logic -radix hexadecimal /sram_bus_TB_v/nwe
add wave -noupdate -format Logic -radix hexadecimal /sram_bus_TB_v/ncs
add wave -noupdate -format Logic -radix hexadecimal /sram_bus_TB_v/noe
add wave -noupdate -format Logic -radix hexadecimal /sram_bus_TB_v/reset
add wave -noupdate -format Logic -radix hexadecimal /sram_bus_TB_v/led
add wave -noupdate -format Literal -radix hexadecimal {/sram_bus_TB_v/sram_data$inout$reg}
add wave -noupdate -format Logic -radix hexadecimal /sram_bus_TB_v/sram_data
add wave -noupdate -format Literal -radix hexadecimal /sram_bus_TB_v/data_tx
add wave -noupdate -format Logic -radix hexadecimal /glbl/GSR
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {154070 ps} 0}
configure wave -namecolwidth 323
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 0
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
update
WaveRestoreZoom {0 ps} {656250 ps}

View File

@@ -0,0 +1,44 @@
NET clk LOC = "P38";
NET reset LOC = "P30";
NET led LOC = "P44";
NET irq_pin LOC = "P71";
#ADDRESS BUS
NET "addr<12>" LOC = "P90";
NET "addr<11>" LOC = "P91";
NET "addr<10>" LOC = "P85";
NET "addr<9>" LOC = "P92";
NET "addr<8>" LOC = "P94";
NET "addr<7>" LOC = "P95";
NET "addr<6>" LOC = "P98";
NET "addr<5>" LOC = "P3";
NET "addr<4>" LOC = "P2";
NET "addr<3>" LOC = "P78";
NET "addr<2>" LOC = "P79";
NET "addr<1>" LOC = "P83";
NET "addr<0>" LOC = "P84";
#DATA BUS
NET "sram_data<7>" LOC = "P4";
NET "sram_data<6>" LOC = "P5";
NET "sram_data<5>" LOC = "P9";
NET "sram_data<4>" LOC = "P10";
NET "sram_data<3>" LOC = "P11";
NET "sram_data<2>" LOC = "P12";
NET "sram_data<1>" LOC = "P15";
NET "sram_data<0>" LOC = "P16";
#CONTROL BUS
NET "nwe" LOC = "P88";
NET "noe" LOC = "P86";
NET "ncs" LOC = "P69";
#ADC
#NET "ADC_EOC" LOC = "P17";
#NET "ADC_SCLK" LOC = "P18";
#NET "ADC_SDIN" LOC = "P22";
#NET "ADC_SDOUT" LOC = "P23";
#NET "ADC_CS" LOC = "P24";
#NET "ADC_CSTART" LOC = "P26";

View File

@@ -0,0 +1,83 @@
`timescale 1ns / 1ps
module sram_bus(clk, sram_data, addr, nwe, ncs, noe, reset, led, irq_pin);
parameter B = (7);
input clk, nwe, ncs, noe, reset;
input [12:0] addr;
inout [B:0] sram_data;
output led;
input irq_pin;
// synchronize signals
reg sncs, snwe;
reg [12:0] buffer_addr;
reg [B:0] buffer_data;
// interfaz fpga signals
// wire [12:0] addr;
// bram interfaz signals
reg we;
reg w_st;
reg [B:0] wdBus;
wire [B:0] rdBus;
// interefaz signals assignments
wire T = ~noe | ncs;
assign sram_data = T?8'bZ:rdBus;
//--------------------------------------------------------------------------
// synchronize assignment
always @(negedge clk)
begin
sncs <= ncs;
snwe <= nwe;
buffer_data <= sram_data;
buffer_addr <= addr;
end
// write access cpu to bram
always @(posedge clk)
if(~reset) {w_st, we, wdBus} <= 0;
else begin
wdBus <= buffer_data;
case (w_st)
0: begin
we <= 0;
if(sncs | snwe) w_st <= 1;
end
1: begin
if(~(sncs | snwe)) begin
we <= 1;
w_st <= 0;
end
else we <= 0;
end
endcase
end
RAMB16_S2 ba0( .CLK(~clk), .EN(1'b1), .SSR(1'b0), .ADDR(buffer_addr),
.WE(we), .DI(wdBus[1:0]), .DO(rdBus[1:0]) );
RAMB16_S2 ba1( .CLK(~clk), .EN(1'b1), .SSR(1'b0), .ADDR(buffer_addr),
.WE(we), .DI(wdBus[3:2]), .DO(rdBus[3:2]) );
RAMB16_S2 ba2( .CLK(~clk), .EN(1'b1), .SSR(1'b0), .ADDR(buffer_addr),
.WE(we), .DI(wdBus[5:4]), .DO(rdBus[5:4]) );
RAMB16_S2 ba3( .CLK(~clk), .EN(1'b1), .SSR(1'b0), .ADDR(buffer_addr),
.WE(we), .DI(wdBus[7:6]), .DO(rdBus[7:6]) );
reg [24:0] counter;
always @(posedge clk) begin
if (~reset)
counter <= {25{1'b0}};
else
counter <= counter + 1;
end
assign led = counter[24];
endmodule

View File

@@ -0,0 +1,113 @@
`timescale 1ns / 1ps
module sram_bus_TB;
// inputs
reg clk;
reg [12:0] addr;
reg nwe;
reg ncs;
reg noe;
reg reset;
// leds
reg led;
// Bidirs
reg [7:0] sram_data$inout$reg ;
// Instantiate the Unit Under Test (UUT)
sram_bus uut ( .clk(clk), .reset(reset),
.sram_data(sram_data), .addr(addr), .nwe(nwe),
.ncs(ncs), .noe(noe)
);
parameter PERIOD = 20;
parameter real DUTY_CYCLE = 0.5;
parameter OFFSET = 0;
parameter TSET = 3;
parameter THLD = 3;
parameter NWS = 3;
parameter CAM_OFF = 4000;
reg [15:0] i;
reg [15:0] j;
reg [15:0] k;
reg [15:0] data_tx;
event reset_trigger;
event reset_done_trigger;
initial begin // Reset the system, Start the image capture process
forever begin
@ (reset_trigger);
@ (negedge clk);
reset = 1;
@ (negedge clk);
reset = 0;
-> reset_done_trigger;
end
end
initial begin // Initialize Inputs
clk = 0; addr = 0; nwe = 1; ncs = 1; noe = 1;
end
initial begin // Process for clk
#OFFSET;
forever
begin
clk = 1'b0;
#(PERIOD-(PERIOD*DUTY_CYCLE)) clk = 1'b1;
#(PERIOD*DUTY_CYCLE);
end
end
initial begin: TEST_CASE
#10 -> reset_trigger;
@ (reset_done_trigger);
// Write data to SRAM
for(i=0; i<10; i=i+1) begin
@ (posedge clk);
ncs <= 0;
addr <= i[9:0];
repeat (TSET) begin
@ (posedge clk);
end
nwe <= 0;
sram_data$inout$reg <= i*2;
repeat (NWS) begin
@ (posedge clk);
end
nwe <= 1;
repeat (THLD) begin
@ (posedge clk);
end
ncs <= 1;
sram_data$inout$reg = {16{1'bz}};
end
nwe = 1;
//Read Data
for(i=0; i<10; i=i+1) begin
@ (posedge clk);
ncs <= 0;
addr <= i[9:0];
repeat (TSET) begin
@ (posedge clk);
end
noe <= 0;
sram_data$inout$reg <= i;
repeat (NWS) begin
@ (posedge clk);
end
noe <= 1;
repeat (THLD) begin
@ (posedge clk);
end
ncs <= 1;
sram_data$inout$reg = {16{1'bz}};
end
end
endmodule

View File

@@ -0,0 +1,45 @@
CC = mipsel-openwrt-linux-gcc
all: jz_init_sram jz_test_gpio enable_rx enable_irq
DEBUG = -O3 -g0
COMMON_SOURCES = jz47xx_gpio.c jz47xx_mmap.c
H_SOURCES = jz47xx_gpio.h jz47xx_mmap.h
INCLUDE = -I.
WARNINGS= -Wcast-align -Wpacked -Wpadded -Wall
CCFLAGS = ${INCLUDE} ${DEBUG} ${WARNINGS}
LDFLAGS =
COMMON_OBJECTS = $(COMMON_SOURCES:.c=.o)
NANO_IP = 192.168.254.101
jz_init_sram: $(COMMON_OBJECTS)
$(CC) $(LDFLAGS) $(COMMON_OBJECTS) jz_init_sram.c -o jz_init_sram
jz_test_gpio: $(COMMON_OBJECTS)
$(CC) $(LDFLAGS) $(COMMON_OBJECTS) jz_test_gpio.c -o jz_test_gpio
enable_rx: $(COMMON_OBJECTS)
$(CC) $(LDFLAGS) $(COMMON_OBJECTS) enable_rx.c -o enable_rx
enable_irq: $(COMMON_OBJECTS)
$(CC) $(LDFLAGS) $(COMMON_OBJECTS) enable_irq.c -o enable_irq
.c.o:
$(CC) -c $(CCFLAGS) $< -o $@
upload: jz_init_sram jz_test_gpio
scp jz_test_gpio jz_init_sram root@$(NANO_IP):
clean:
rm -f *.o jz_init_sram jz_test_gpio enable_rx ${EXEC} *~ enable_irq
indent:
indent -bad -bap -nbc -bl -nce -i2 --no-tabs --line-length120 $(COMMON_SOURCES) $(H_SOURCES)

View File

@@ -0,0 +1,40 @@
/*
JZ47xx test gpio
Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com
Carlos Camargo cicamargoba@unal.edu.co
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <stdio.h>
#include <unistd.h>
#include "jz47xx_gpio.h"
#define IRQ_PORT JZ_GPIO_PORT_C
#define IRQ_PIN 15
int
main ()
{
JZ_PIO *pio = jz_gpio_map (IRQ_PORT);
if (!pio)
return -1;
jz_gpio_as_irq (pio, IRQ_PIN);
return 0;
}

View File

@@ -0,0 +1,40 @@
/*
JZ47xx test gpio
Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com
Carlos Camargo cicamargoba@unal.edu.co
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <stdio.h>
#include <unistd.h>
#include "jz47xx_gpio.h"
#define RXD_PORT JZ_GPIO_PORT_D
#define RXD_PIN 26
int
main ()
{
JZ_PIO *pio = jz_gpio_map (RXD_PORT);
if (!pio)
return -1;
jz_gpio_as_func (pio, RXD_PIN, 1);
return 0;
}

View File

@@ -0,0 +1,119 @@
/*
JZ47xx GPIO at userspace
Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <jz47xx_gpio.h>
#include <jz47xx_mmap.h>
#define JZ_GPIO_BASE 0x10010000
void
jz_gpio_as_output (JZ_PIO * pio, unsigned int o)
{
pio->PXFUNC = (1 << (o));
pio->PXSELC = (1 << (o));
pio->PXDIRS = (1 << (o));
}
void
jz_gpio_as_input (JZ_PIO * pio, unsigned int o)
{
pio->PXFUNC = (1 << (o));
pio->PXSELC = (1 << (o));
pio->PXDIRC = (1 << (o));
}
void
jz_gpio_as_irq (JZ_PIO * pio, unsigned int o)
{
pio->PXFUNC = (1 << (o));
pio->PXSELS = (1 << (o));
pio->PXDIRC = (1 << (o));
}
void
jz_gpio_set_pin (JZ_PIO * pio, unsigned int o)
{
pio->PXDATS = (1 << (o));
}
void
jz_gpio_clear_pin (JZ_PIO * pio, unsigned int o)
{
pio->PXDATC = (1 << (o));
}
void
jz_gpio_out (JZ_PIO * pio, unsigned int o, unsigned int val)
{
if (val == 0)
pio->PXDATC = (1 << (o));
else
pio->PXDATS = (1 << (o));
}
unsigned int
jz_gpio_get_pin (JZ_PIO * pio, unsigned int o)
{
return (pio->PXPIN & (1 << o)) ? 1 : 0;
}
int
jz_gpio_as_func (JZ_PIO * pio, unsigned int o, int func)
{
switch (func)
{
case 0:
pio->PXFUNS = (1 << o);
pio->PXTRGC = (1 << o);
pio->PXSELC = (1 << o);
pio->PXPES = (1 << o);
return 1;
case 1:
pio->PXFUNS = (1 << o);
pio->PXTRGC = (1 << o);
pio->PXSELS = (1 << o);
pio->PXPES = (1 << o);
return 1;
case 2:
pio->PXFUNS = (1 << o);
pio->PXTRGS = (1 << o);
pio->PXSELC = (1 << o);
pio->PXPES = (1 << o);
return 1;
}
return 0;
}
JZ_PIO *
jz_gpio_map (int port)
{
JZ_PIO *pio;
pio = (JZ_PIO *) jz_mmap (JZ_GPIO_BASE);
pio = (JZ_PIO *) ((unsigned int) pio + port * 0x100);
return pio;
}

View File

@@ -0,0 +1,84 @@
/*
JZ47xx GPIO at userspace
Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef __jz47xx_gpio_h__
#define __jz47xx_gpio_h__
#define JZ_GPIO_PORT_A 0
#define JZ_GPIO_PORT_B 1
#define JZ_GPIO_PORT_C 2
#define JZ_GPIO_PORT_D 3
typedef volatile unsigned int JZ_REG; /* Hardware register definition */
typedef struct _JZ_PIO
{
JZ_REG PXPIN; /* PIN Level Register */
JZ_REG Reserved0;
JZ_REG Reserved1;
JZ_REG Reserved2;
JZ_REG PXDAT; /* Port Data Register */
JZ_REG PXDATS; /* Port Data Set Register */
JZ_REG PXDATC; /* Port Data Clear Register */
JZ_REG Reserved3;
JZ_REG PXIM; /* Interrupt Mask Register */
JZ_REG PXIMS; /* Interrupt Mask Set Reg */
JZ_REG PXIMC; /* Interrupt Mask Clear Reg */
JZ_REG Reserved4;
JZ_REG PXPE; /* Pull Enable Register */
JZ_REG PXPES; /* Pull Enable Set Reg. */
JZ_REG PXPEC; /* Pull Enable Clear Reg. */
JZ_REG Reserved5;
JZ_REG PXFUN; /* Function Register */
JZ_REG PXFUNS; /* Function Set Register */
JZ_REG PXFUNC; /* Function Clear Register */
JZ_REG Reserved6;
JZ_REG PXSEL; /* Select Register */
JZ_REG PXSELS; /* Select Set Register */
JZ_REG PXSELC; /* Select Clear Register */
JZ_REG Reserved7;
JZ_REG PXDIR; /* Direction Register */
JZ_REG PXDIRS; /* Direction Set Register */
JZ_REG PXDIRC; /* Direction Clear Register */
JZ_REG Reserved8;
JZ_REG PXTRG; /* Trigger Register */
JZ_REG PXTRGS; /* Trigger Set Register */
JZ_REG PXTRGC; /* Trigger Set Register */
JZ_REG Reserved9;
JZ_REG PXFLG; /* Port Flag Register */
JZ_REG PXFLGC; /* Port Flag clear Register */
} JZ_PIO, *PJZ_PIO;
void jz_gpio_as_output (JZ_PIO * pio, unsigned int o);
void jz_gpio_as_input (JZ_PIO * pio, unsigned int o);
void jz_gpio_set_pin (JZ_PIO * pio, unsigned int o);
void jz_gpio_clear_pin (JZ_PIO * pio, unsigned int o);
void jz_gpio_out (JZ_PIO * pio, unsigned int o, unsigned int val);
unsigned int jz_gpio_get_pin (JZ_PIO * pio, unsigned int o);
int jz_gpio_as_func (JZ_PIO * pio, unsigned int o, int func);
JZ_PIO *jz_gpio_map (int port);
#endif

View File

@@ -0,0 +1,64 @@
/*
* JZ47xx GPIO lines
*
* Written 2010 by Andres Calderon andres.calderon@emqbit.com
*/
#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <jz47xx_mmap.h>
void *
jz_mmap (off_t address)
{
int fd;
void *pio;
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC)) == -1)
{
fprintf (stderr, "Cannot open /dev/mem.\n");
return 0;
}
pio = (void *) mmap (0, getpagesize (), PROT_READ | PROT_WRITE, MAP_SHARED, fd, address);
if (pio == (void *) -1)
{
fprintf (stderr, "Cannot mmap.\n");
return 0;
}
return pio;
}
void *
jz_fpga_map (off_t address)
{
int fd;
void *fpga;
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC)) == -1)
{
fprintf (stderr, "Cannot open /dev/mem.\n");
return 0;
}
fpga = (void *) mmap (0, FPGA_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, address);
if (fpga == (void *) -1)
{
fprintf (stderr, "Cannot mmap.\n");
return 0;
}
return fpga;
}

View File

@@ -0,0 +1,17 @@
/*
* JZ47xx GPIO lines
*
* Written 2010 by Andres Calderon andres.calderon@emqbit.com
*/
#ifndef __jz47xx_mmap_h__
#define __jz47xx_mmap_h__
#include <sys/mman.h>
#define FPGA_SIZE (1 << 15)
void *jz_mmap (off_t address);
void *jz_fpga_map (off_t address);
#endif

View File

@@ -0,0 +1,75 @@
/* SAKC FPGA/SRAM interface test
Copyright (C) 2010 Carlos Camargo cicamargoba@unal.edu.co
Andres Calderon andres.calderon@emqbit.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "jz47xx_gpio.h"
#include "jz47xx_mmap.h"
#define CS2_PORT JZ_GPIO_PORT_B
#define CS2_PIN 26
int
main ()
{
int i;
JZ_PIO *pio;
int *virt_addr;
pio = jz_gpio_map (CS2_PORT);
jz_gpio_as_func (pio, CS2_PIN, 0);
virt_addr = (int *) jz_mmap (0x13010000) + 0x18;
if (*virt_addr != 0xFFF7700)
{ // 0 WS, 8 bits
*virt_addr = 0xFFF7700;
printf ("Configuring CS2 8 bits \n");
}
else
printf ("CS3, already configured\n");
virt_addr = (int *) jz_fpga_map (0x15000000);
printf ("Writing Memory..\n");
srand48(0x3c);
for (i = 0; i < FPGA_SIZE/4; i++)
virt_addr[i] = (lrand48() & 0x00ff);
printf ("Reading Memory..\n");
srand48(0x3c);
for (i = 0; i < FPGA_SIZE/4; i++){
printf("%X\n", virt_addr[i]);
if (virt_addr[i] != (lrand48() & 0x00ff)){
printf ("FPGA - Xburst connection test failed on Address:0x%x\n", i);
return 1; /* Error */
}
}
printf ("%d\n", i);
printf ("FPGA - Xburst connection test passed\n");
return 0;
}

View File

@@ -0,0 +1,59 @@
/*
JZ47xx test gpio
Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com
Carlos Camargo cicamargoba@unal.edu.co
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <stdio.h>
#include <unistd.h>
#include "jz47xx_gpio.h"
//#define TEST_PORT JZ_GPIO_PORT_C
//#define TEST_PIN 17
int
main (int argc,char *argv[])
{
int TEST_PORT, TEST_PIN;
if(argc != 3){
fprintf(stderr,"\nUsage: %s TEST_PIN_PORT(A=0, B=1, C=2, D=3) TEST_PIN \n",argv[0]);
}
TEST_PORT = ;
TEST_PIN = ;
JZ_PIO *pio = jz_gpio_map (TEST_PORT);
if (!pio)
return -1;
jz_gpio_as_output (pio, TEST_PIN);
int tg = 1;
while (1)
{
jz_gpio_out (pio, TEST_PIN, tg);
printf ("[%d]", jz_gpio_get_pin (pio, TEST_PIN));
fflush (stdout);
usleep (500 * 1000);
tg = !tg;
}
return 0;
}