aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp2/models/CY7C1356C/cy1356.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp2/models/CY7C1356C/cy1356.v')
-rw-r--r--fpga/usrp2/models/CY7C1356C/cy1356.v502
1 files changed, 502 insertions, 0 deletions
diff --git a/fpga/usrp2/models/CY7C1356C/cy1356.v b/fpga/usrp2/models/CY7C1356C/cy1356.v
new file mode 100644
index 000000000..ab7ace610
--- /dev/null
+++ b/fpga/usrp2/models/CY7C1356C/cy1356.v
@@ -0,0 +1,502 @@
+//
+// Copyright 2011 Ettus Research LLC
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+//
+
+`define sb200
+//************************************************************************
+//************************************************************************
+//** This model is the property of Cypress Semiconductor Corp and is **
+//** protected by the US copyright laws, any unauthorized copying and **
+//** distribution is prohibited. Cypress reserves the right to change **
+//** any of the functional specifications without any prior notice. **
+//** Cypress is not liable for any damages which may result from the **
+//** use of this functional model. **
+//** **
+//** File Name : CY7C1356 **
+//** **
+//** Revision : 1.0 - 08/03/2004 **
+//** **
+//** The timings are to be selected by the user depending upon the **
+//** frequency of operation from the datasheet. **
+//** **
+//** Model : CY7C1356C - NoBL Pipelined SRAM **
+//** Queries : MPD Applications **
+//** Website: www.cypress.com/support **
+//************************************************************************
+//************************************************************************
+
+`timescale 1ns / 10ps
+
+// NOTE : Any setup/hold errors will force input signal to x state
+// or if results indeterminant (write addr) core is reset x
+
+// define fixed values
+
+`define wordsize (18 -1) //
+`define no_words (1048576 -1) // 1M x 18 RAM
+
+module cy1356 ( d, clk, a, bws, we_b, adv_lb, ce1b, ce2, ce3b, oeb, cenb, mode);
+
+inout [`wordsize:0] d;
+input clk, // clock input (R)
+ we_b, // byte write enable(L)
+ adv_lb, // burst(H)/load(L) address
+ ce1b, // chip enable(L)
+ ce2, // chip enable(H)
+ ce3b, // chip enable(L)
+ oeb, // async output enable(L)(read)
+ cenb, // clock enable(L)
+ mode; // interleave(H)/linear(L) burst
+input [1:0] bws; // byte write select(L)
+input [18:0] a; // address bus
+
+// *** NOTE DEVICE OPERATES #0.01 AFTER CLOCK ***
+// *** THEREFORE DELAYS HAVE TO TAKE THIS INTO ACCOUNT ***
+
+
+//**********************************************************************
+// Timings for 225MHz
+//**********************************************************************
+`ifdef sb225
+ `define teohz #2.8
+ `define teolz #0
+ `define tchz #2.8
+ `define tclz #1.25
+
+ `define tco #2.8
+ `define tdoh #1.25
+ `define tas 1.4
+ `define tah 0.4
+`endif
+//***********************************************************************
+// Timings for 200MHz
+//**********************************************************************
+`ifdef sb200
+ `define teohz #3.2
+ `define teolz #0
+ `define tchz #3.2
+ `define tclz #1.5
+
+ `define tco #3.2
+ `define tdoh #1.5
+
+ `define tas 1.5
+ `define tah 0.5
+`endif
+//***********************************************************************
+
+//**********************************************************************
+// This model is configured for 166 MHz Operation (CY7C1356-166).
+//**********************************************************************
+`ifdef sb166
+ `define teohz #3.5
+ `define teolz #0
+ `define tchz #3.5
+ `define tclz #1.5
+
+ `define tco #3.5
+ `define tdoh #1.5
+
+ `define tas 1.5
+ `define tah 0.5
+`endif
+
+reg notifier; // error support reg's
+reg noti1_0;
+reg noti1_1;
+reg noti1_2;
+reg noti1_3;
+reg noti1_4;
+reg noti1_5;
+reg noti1_6;
+reg noti2;
+
+
+wire chipen; // combined chip enable (high for an active chip)
+
+reg chipen_d; // _d = delayed
+reg chipen_o; // _o = operational = delayed sig or _d sig
+
+wire writestate; // holds 1 if any of writebus is low
+reg writestate_d;
+reg writestate_o;
+
+wire loadcyc; // holds 1 for load cycles (setup and hold checks)
+wire writecyc; // holds 1 for write cycles (setup and hold checks)
+wire [1:0] bws; // holds the bws values
+
+wire [1:0] writebusb; // holds the "internal" bws bus based on we_b
+reg [1:0] writebusb_d;
+reg [1:0] writebusb_o;
+
+wire [2:0] operation; // holds chipen, adv_ld and writestate
+reg [2:0] operation_d;
+reg [2:0] operation_o;
+
+wire [18:0] a; // address input bus
+reg [18:0] a_d;
+reg [18:0] a_o;
+
+reg [`wordsize:0] do; // data output reg
+reg [`wordsize:0] di; // data input bus
+reg [`wordsize:0] dd; // data delayed bus
+
+wire tristate; // tristate output (on a bytewise basis) when asserted
+reg cetri; // register set by chip disable which sets the tristate
+reg oetri; // register set by oe which sets the tristate
+reg enable; // register to make the ram enabled when equal to 1
+reg [18:0] addreg; // register to hold the input address
+reg [`wordsize:0] pipereg; // register for the output data
+
+reg [`wordsize:0] mem [0:`no_words]; // RAM array
+
+reg [`wordsize:0] writeword; // temporary holding register for the write data
+reg burstinit; // register to hold a[0] for burst type
+reg [18:0] i; // temporary register used to write to all mem locs.
+reg writetri; // tristate
+reg lw, bw; // pipelined write functions
+reg we_bl;
+
+
+wire [`wordsize:0] d = !tristate ? do[`wordsize:0] : 18'bz ; // data bus
+
+assign chipen = (adv_lb == 1 ) ? chipen_d :
+ ~ce1b & ce2 & ~ce3b ;
+
+assign writestate = ~& writebusb;
+
+assign operation = {chipen, adv_lb, writestate};
+
+assign writebusb[1:0] = ( we_b ==0 & adv_lb ==0) ? bws[1:0]:
+ ( we_b ==1 & adv_lb ==0) ? 2'b11 :
+ ( we_bl ==0 & adv_lb ==1) ? bws[1:0]:
+ ( we_bl ==1 & adv_lb ==1) ? 2'b11 :
+ 2'bxx ;
+
+assign loadcyc = chipen & !cenb;
+
+assign writecyc = writestate_d & enable & ~cenb & chipen; // check
+
+assign tristate = cetri | writetri | oetri;
+
+pullup (mode);
+
+// formers for notices/errors etc
+//
+//$display("NOTICE : xxx :");
+//$display("WARNING : xxx :");
+//$display("ERROR *** : xxx :");
+
+
+// initialize the output to be tri-state, ram to be disabled
+
+initial
+ begin
+// signals
+
+ writetri = 0;
+ cetri = 1;
+ enable = 0;
+ lw = 0;
+ bw = 0;
+
+// error signals
+
+ notifier = 0;
+ noti1_0 = 0;
+ noti1_1 = 0;
+ noti1_2 = 0;
+ noti1_3 = 0;
+ noti1_4 = 0;
+ noti1_5 = 0;
+ noti1_6 = 0;
+ noti2 = 0;
+
+end
+
+
+
+// asynchronous OE
+
+always @(oeb)
+begin
+ if (oeb == 1)
+ oetri <= `teohz 1;
+ else
+ oetri <= `teolz 0;
+end
+
+// *** SETUP / HOLD VIOLATIONS ***
+
+always @(noti2)
+begin
+$display("NOTICE : 020 : Data bus corruption");
+ force d =18'bx;
+ #1;
+ release d;
+end
+
+always @(noti1_0)
+begin
+$display("NOTICE : 010 : Byte write corruption");
+ force bws = 2'bx;
+ #1;
+ release bws;
+end
+
+always @(noti1_1)
+begin
+$display("NOTICE : 011 : Byte enable corruption");
+ force we_b = 1'bx;
+ #1;
+ release we_b;
+end
+
+always @(noti1_2)
+begin
+$display("NOTICE : 012 : CE1B corruption");
+ force ce1b =1'bx;
+ #1;
+ release ce1b;
+end
+
+always @(noti1_3)
+begin
+$display("NOTICE : 013 : CE2 corruption");
+ force ce2 =1'bx;
+ #1;
+ release ce2;
+end
+
+always @(noti1_4)
+begin
+$display("NOTICE : 014 : CE3B corruption");
+ force ce3b =1'bx;
+ #1;
+ release ce3b;
+end
+
+always @(noti1_5)
+begin
+$display("NOTICE : 015 : CENB corruption");
+ force cenb =1'bx;
+ #1;
+ release cenb;
+end
+
+always @(noti1_6)
+begin
+$display("NOTICE : 016 : ADV_LB corruption");
+ force adv_lb = 1'bx;
+ #1;
+ release adv_lb;
+end
+
+// synchronous functions from clk edge
+
+always @(posedge clk)
+if (!cenb)
+begin
+#0.01;
+ // latch conditions on adv_lb
+
+ if (adv_lb)
+ we_bl <= we_bl;
+ else
+ we_bl <= we_b;
+
+ chipen_d <= chipen;
+
+
+ chipen_o <= chipen;
+ writestate_o <= writestate;
+ writestate_d <= writestate_o;
+ writebusb_o <= writebusb;
+ writebusb_d <= writebusb_o;
+ operation_o <= operation;
+ a_o <= a;
+ a_d <= a_o;
+ di = d;
+
+ // execute previously pipelined fns
+
+ if (lw) begin
+ loadwrite;
+ lw =0;
+ end
+
+ if (bw) begin
+ burstwrite;
+ bw =0;
+ end
+
+ // decode input/piplined state
+
+ casex (operation_o)
+ 3'b0?? : turnoff;
+ 3'b101 : setlw;
+ 3'b111 : setbw;
+ 3'b100 : loadread;
+ 3'b110 : burstread;
+ default : unknown; // output unknown values and display an error message
+ endcase
+
+ do <= `tco pipereg;
+
+end
+
+// *** task section ***
+
+task read;
+begin
+ if (enable) cetri <= `tclz 0;
+ writetri <= `tchz 0;
+ do <= `tdoh 18'hx;
+ pipereg = mem[addreg];
+end
+endtask
+
+task write;
+begin
+ if (enable) cetri <= `tclz 0;
+ writeword = mem[addreg]; // set up a word to hold the data for the current location
+ /* overwrite the current word for the bytes being written to */
+ if (!writebusb_d[1]) writeword[17:9] = di[17:9];
+ if (!writebusb_d[0]) writeword[8:0] = di[8:0];
+ writeword = writeword & writeword; //convert z to x states
+ mem[addreg] = writeword; // store the new word into the memory location
+ //writetri <= `tchz 1; // tristate the outputs
+end
+endtask
+
+task setlw;
+begin
+ lw =1;
+ writetri <= `tchz 1; // tristate the outputs
+end
+endtask
+
+task setbw;
+begin
+ bw =1;
+ writetri <= `tchz 1; // tristate the outputs
+end
+endtask
+
+task loadread;
+begin
+ burstinit = a_o[0];
+ addreg = a_o;
+ enable = 1;
+ read;
+end
+endtask
+
+task loadwrite;
+begin
+ burstinit = a_d[0];
+ addreg = a_d;
+ enable = 1;
+ write;
+end
+endtask
+
+task burstread;
+begin
+ burst;
+ read;
+end
+endtask
+
+task burstwrite;
+begin
+ burst;
+ write;
+end
+endtask
+
+task unknown;
+begin
+ do = 18'bx;
+ // $display ("Unknown function: Operation = %b\n", operation);
+end
+endtask
+
+task turnoff;
+begin
+ enable = 0;
+ cetri <= `tchz 1;
+ pipereg = 18'h0;
+end
+endtask
+
+task burst;
+begin
+ if (burstinit == 0 || mode == 0)
+ begin
+ case (addreg[1:0])
+ 2'b00: addreg[1:0] = 2'b01;
+ 2'b01: addreg[1:0] = 2'b10;
+ 2'b10: addreg[1:0] = 2'b11;
+ 2'b11: addreg[1:0] = 2'b00;
+ default: addreg[1:0] = 2'bxx;
+ endcase
+ end
+ else
+ begin
+ case (addreg[1:0])
+ 2'b00: addreg[1:0] = 2'b11;
+ 2'b01: addreg[1:0] = 2'b00;
+ 2'b10: addreg[1:0] = 2'b01;
+ 2'b11: addreg[1:0] = 2'b10;
+ default: addreg[1:0] = 2'bxx;
+ endcase
+ end
+end
+endtask
+
+// IO checks
+
+specify
+// specify the setup and hold checks
+
+// notifier will wipe memory as result is indeterminent
+
+$setuphold(posedge clk &&& loadcyc, a, `tas, `tah, notifier);
+
+// noti1 should make ip = 'bx;
+
+$setuphold(posedge clk, bws, `tas, `tah, noti1_0);
+
+$setuphold(posedge clk, we_b, `tas, `tah, noti1_1);
+$setuphold(posedge clk, ce1b, `tas, `tah, noti1_2);
+$setuphold(posedge clk, ce2, `tas, `tah, noti1_3);
+$setuphold(posedge clk, ce3b, `tas, `tah, noti1_4);
+
+// noti2 should make d = 18'hxxxxx;
+
+$setuphold(posedge clk &&& writecyc, d, `tas, `tah, noti2);
+
+// add extra tests here.
+
+$setuphold(posedge clk, cenb, `tas, `tah, noti1_5);
+$setuphold(posedge clk, adv_lb, `tas, `tah, noti1_6);
+
+endspecify
+
+endmodule
+
+