// --------------------------------------------------------------------
// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------------------
// Copyright (c) 2005 by Lattice Semiconductor Corporation
// --------------------------------------------------------------------
//
// Permission:
//
//   Lattice Semiconductor grants permission to use this code for use
//   in synthesis for any Lattice programmable logic product.  Other
//   use of this code, including the selling or duplication of any
//   portion is strictly prohibited.
//
// Disclaimer:
//
//   This VHDL or Verilog source code is intended as a design reference
//   which illustrates how these types of functions can be implemented.
//   It is the user's responsibility to verify their design for
//   consistency and functionality through the use of formal
//   verification methods.  Lattice Semiconductor provides no warranty
//   regarding the use or functionality of this code.
//
// --------------------------------------------------------------------
//
//                     Lattice Semiconductor Corporation
//                     5555 NE Moore Court
//                     Hillsboro, OR 97214
//                     U.S.A
//
//                     TEL: 1-800-Lattice (USA and Canada)
//                          408-826-6000 (other locations)
//
//                     web: http://www.latticesemi.com/
//                     email: techsupport@latticesemi.com
//
// --------------------------------------------------------------------
//
//  Project:           FCRAM memory test
//  File:              fcram_test_top.v
//  Title:             fcram_test_top
//  Description:       This is the top level module of FCRAM memory test
//                     design running at 166.66MHz on LatticeEC Advanced
//                     Evaluation Board.
//
// --------------------------------------------------------------------
//
// Revision History :
// --------------------------------------------------------------------
// $Log: fcram_test_top.v,v $
// Revision 1.0  2005-06-28 13:29:11-07  jhsin
// Initial revision
//
// --------------------------------------------------------------------

`include "fcram_params.v"
`timescale 100ps / 10ps

module fcram_test_top
  (
   //-------INPUTS
   clk_in,           // 33MHz System clock
   rst_n,            // Generic I/F Active low system reset

   vref1A,
   vref2A,
   vref1B,
   vref2B,

   //-------OUTPUTS
   ledout,           // Generic I/F LED output Bus
   debug_port_a,     // Debug Output Port A
   debug_port_b,     // Debug Output Port B
   debug_port_c,     // Debug Output Port C

   // Bi-directional databus to external memory
   fcram_dq,         // FCRAM Data bus output
   fcram_dqs,        // FCRAM Data strobe output

   // Output to External memory
   // FCRAM Address, controls and clock
   fcram_clk,        // FCRAM clock
   fcram_clkn,       // FCRAM Inverted clock
   fcram_pdn,        // FCRAM Power Down Control
   fcram_csn,        // FCRAM Chip select
   fcram_fn,         // FCRAM Function Control
   fcram_addr,       // FCRAM Address bus
   fcram_ba          // FCRAM Bank bus
);

// ====================================================================
// Define all inputs / outputs
// ====================================================================
//--------Inputs
input                      clk_in;       // System clock
input                      rst_n;        // Generic I/F Active low system reset

input                      vref1A;
input                      vref2A;
input                      vref1B;
input                      vref2B;

//-------OUTPUTS
output [7:0]               ledout;       // Generic I/F LED Output Bus
output [15:0]              debug_port_a; // Debug Output Port A
output [15:0]              debug_port_b; // Debug Output Port B
output [19:0]              debug_port_c; // Debug Output Port C

// Bi-directional databus to external memory
inout [`DQ_WIDTH-1:0]      fcram_dq;     // FCRAM Data bus output
inout [`DQ_GROUPS-1:0]     fcram_dqs;    // FCRAM Data strobe output

// Output to External memory
// FCRAM Address, controls and clock
output                     fcram_clk;    // FCRAM clock
output                     fcram_clkn;   // FCRAM Inverted clock
output                     fcram_pdn;    // FCRAM Power Down Control
output                     fcram_csn;    // FCRAM Chip select
output                     fcram_fn;     // FCRAM Function Control
output [14:0]              fcram_addr;   // FCRAM Address bus
output [1:0]               fcram_ba;     // FCRAM Bank bus

// ====================================================================
// Internal signals
// ====================================================================

//---- Wires
wire                       pll_clk;
wire [3:0]                 number_of_tests_passed;
wire [3:0]                 number_of_tests_failed;

wire [2:0]                 usr_cmdi;        // Generic I/F Command for controller
                                            // 000  NOP
                                            // 100  WRITE
                                            // 101  SELFR
                                            // 110  READ
                                            // 111  AUTOR

wire [`ADDR_WIDTH-1:0]     addr;            // Generic I/F Address bus
wire                       cmd_valid;
wire                       init_start;
wire [4:0]                 burst_count;
wire [`DSIZE-1:0]          write_data;      // Generic I/F Data input bus
wire                       cmd_rdy_n;       // Generic I/F Busy signal
wire                       data_rdy;        // Generic I/F indicates controller has
                                            // accepted a data from Datain bus
wire [`DSIZE-1:0]          read_data;       // Generic I/F Data output bus
wire                       read_data_valid; // Generic I/F indicates Dataout bus has
                                            // a valid data

wire                       fsm2;
wire [1:0]                 datacheck;
wire [15:0]                latched_data;
wire [7:0]                 test_data;

// ====================================================================
// Instantiate the sub blocks of the top level
// ====================================================================

//
// Wait at least 200 us
// (Osc Freq = 33.33MHz, 24'hffffff = 16777215, 16777215x30ns = 503316450ns = 503.3ms)
//
reg [23:0] wait_200us_count;
reg        waited_200us;

always @(posedge clk_in or negedge rst_n)
begin
   if (~rst_n) begin
      wait_200us_count <= 24'h000000;
      waited_200us <= 1'b0;
   end
   else begin
      wait_200us_count <= wait_200us_count + 1;
      if (wait_200us_count == 24'hffffff) waited_200us <= 1'b1;
   end
end

//
// Create init_done after init_start asserted for a while
// (Osc Freq = 33.33MHz, 8'hff = 255, 255x30ns = 7650ns = 7.65us)
//
reg [7:0] init_done_count;
reg       init_done;

always @(posedge clk_in or negedge rst_n)
begin
   if (~rst_n) begin
      init_done_count <= 8'h00;
      init_done <= 1'b0;
   end
   else begin
      if (init_start) init_done_count <= init_done_count + 1;
      if (init_done_count == 8'hff) init_done <= 1'b1;
   end
end

// ====================================================================
// FCRAM1 Controller
// ====================================================================
fcram_top U1_fcram_top (

   // Clock and reset
   .sys_clk(clk_in),
   .pll_clk(pll_clk),
   .sys_resetn(rst_n),

   // Inputs signals from the User Interface
   .usr_cmdi(usr_cmdi),
   .usr_addri(addr),
   .usr_reset(~init_start),
   .usr_datai(write_data),

   .usr_read_delay(2'b00),
   .usr_num_xfersi(4'b0001),

   // User Interface Output signals
   .usr_dreqo(data_rdy),
   .usr_datao(read_data),
   .usr_dvalo(read_data_valid),
   .usr_acko(cmd_rdy_n),

   .init_bt(1'b0),
   .init_te(1'b0),
   .init_de(1'b0),
   .init_dic(2'b00),
   .ref_burst(4'h8),
   // When 200MHz T_ck = 5ns,
   //   ref_interval(min) =  (400ns x 8)/5ns = 640 = 0x0280
   //   ref_interval(max) =  (7800ns x 8)/5ns = 12480 = 0x30C0
   // When 166MHz T_ck = 6ns,
   //   ref_interval(min) =  (400ns x 8)/6ns = 553 = 0x0229
   //   ref_interval(max) =  (7800ns x 8)/6ns = 10400 = 0x28A0
   // When 133MHz T_ck = 7.5ns,
   //   ref_interval(min) =  (400ns x 8)/7.5ns = 427 = 0x01AB
   //   ref_interval(max) =  (7800ns x 8)/7.5ns = 8230 = 0x2080
   .ref_interval(16'h0300),
   .cntrl_ref_eni(1'b1),

   // Bi-directional databus to external memory
   .ddr_dq(fcram_dq),
   .ddr_dqs(fcram_dqs),

   // Output to External memory
   // FCRAM Address, controls and clock
   .ddr_clk(fcram_clk),
   .ddr_clkn(fcram_clkn),
   .ddr_pdn(fcram_pdn),
   .ddr_csn(fcram_csn),

   .ddr_fn(fcram_fn),
   .ddr_addr(fcram_addr),
   .ddr_ba(fcram_ba)
);

fcram_test U2_fcram_test (

   //-------INPUTS
   .waited_200us(waited_200us),
   .init_done(init_done),
   .pll_clk(pll_clk),
   .rst_n(rst_n),
   .cmd_rdy(~cmd_rdy_n),
   .data_rdy(data_rdy),
   .read_data_valid(read_data_valid),
   .read_data(read_data),

   //-------OUTPUTS
   .init_start(init_start),
   .test_data(test_data),
   .fsm2(fsm2),
   .datacheck(datacheck),
   .latched_data(latched_data),
   .number_of_tests_passed(number_of_tests_passed),
   .number_of_tests_failed(number_of_tests_failed),
   .usr_cmdi(usr_cmdi),
   .cmd_valid(cmd_valid),
   .addr(addr),
   .write_data(write_data)
);

assign ledout = { number_of_tests_passed, number_of_tests_failed };

assign debug_port_a = { cmd_rdy_n,
                        data_rdy,
                        read_data_valid,
                        1'b0,
                        usr_cmdi,
                        addr[17:16],
                        fsm2,
                        init_start,
                        init_done,
                        vref1A,vref1B,vref2A,vref2B };

assign debug_port_b = { addr[15:0] };

assign debug_port_c = { cmd_valid,
                        1'b0,
                        datacheck,
                        latched_data[15:8],
                        test_data };

endmodule
