OpenCores
URL https://opencores.org/ocsvn/common/common/trunk

Subversion Repositories common

[/] [common/] [trunk/] [sram_for_debugging_sync.v] - Rev 48

Compare with Previous | Blame | View Log

//////////////////////////////////////////////////////////////////////
////                                                              ////
//// sram_for_debugging_sync  #(NUM_ADDR_BITS, NUM_DATA_BITS)    ////
////                                                              ////
//// This file is part of the general opencores effort.           ////
//// <http://www.opencores.org/cores/misc/>                       ////
////                                                              ////
//// Module Description:                                          ////
////    An SRAM model which contains only 32 entries.             ////
////    This SRAM trades off time for storage.  By only storing   ////
////      a very few entries, this SRAM takes constant storage    ////
////      independent of how many address lines it exports.       ////
////    The limited storage means that the entries must be read   ////
////      soon after it is written.  If too many writes happen    ////
////      before an entry is read, the entry returns X's.         ////
////    This SRAM has 1 other debugging feature.  When a write    ////
////      is executed, the SRAM ;atches the bit number of the     ////
////      least significant bit of the address which is HIGH.     ////
////    The special address 0xAA00..., with the top 8 bits being  ////
////      8'b1010_1010, returns the stored number when read.      ////
////    As an example, assume that a write is done to location    ////
////      20'h0_0040.                                             ////
////    After the write, but before any other write, the user     ////
////      can read location 20'hC_C000.  The read returns 4'h5.   ////
////                                                              ////
//// Author(s):                                                   ////
//// - Anonymous                                                  ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
////                                                              ////
//// Copyright (C) 2000 Anonymous 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>                   ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
//
// $Id: sram_for_debugging_sync.v,v 1.2 2001-11-06 12:33:15 bbeaver Exp $
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.3  2001/11/06 12:41:27  Blue Beaver
// no message
//
// Revision 1.2  2001/10/02 06:22:08  Blue Beaver
// no message
//
//
 
`timescale 1ns/1ps
 
// instantiate as "sram_for_debugging_sync #(NUM_ADDR_BITS, NUM_DATA_BITS) instance ()"
 
module sram_for_debugging_sync (
  data_out,
  data_in,
  address,
  read_enable,
  write_enable,
  clk
);
  parameter NUM_ADDR_BITS = 1;
  parameter NUM_DATA_BITS = 1;
 
  output [NUM_DATA_BITS - 1 : 0] data_out;
  input  [NUM_DATA_BITS - 1 : 0] data_in;
  input  [NUM_ADDR_BITS - 1 : 0] address;
  input   read_enable;
  input   write_enable;
  input   clk;
 
  reg    [NUM_DATA_BITS - 1 : 0] data_storage [31:0];  // 32 entries of SRAM storage
  reg    [NUM_ADDR_BITS - 1 : 0] address_storage [31:0];  // 32 entries of SRAM storage
  reg    [5:0] write_counter;  // enough to count to 63
  reg    [NUM_DATA_BITS - 1 : 0] stored_write_address;  // store bit number of address LSB set to 1
 
  integer i, j, k, l;
 
// synopsys translate_off
  initial
  begin
    for (i = 6'h00; i != 6'h20; i = i + 6'h01)
    begin
      address_storage[i] = {NUM_ADDR_BITS{1'bX}};
      data_storage[i] = {NUM_DATA_BITS{1'bX}};
      stored_write_address[NUM_DATA_BITS - 1 : 0] = {NUM_DATA_BITS{1'bX}};
      write_counter[5:0] = 6'h00;
    end
  end
// synopsys translate_on
 
// Write to next address, remember which LSB write address bit was ~0
  always @(posedge clk)
  begin
    if (write_enable == 1'b1)
    begin
    $display ("writing %x at %x %t", data_in[NUM_DATA_BITS - 1 : 0], address[NUM_ADDR_BITS - 1 : 0], $time);
      address_storage[write_counter[4:0]] = address[NUM_ADDR_BITS - 1 : 0];
      data_storage[write_counter[4:0]] = data_in[NUM_DATA_BITS - 1 : 0];
      for (j = 0; j < NUM_ADDR_BITS; j = j + 1)
      begin
        if (((address[NUM_ADDR_BITS - 1 : 0] >> j) & 1'b1) != 1'b0)
        begin
          stored_write_address[NUM_DATA_BITS - 1 : 0] = j;
          j = NUM_ADDR_BITS + 1;  // only remember the FIRST bit set
        end
      end
      if (j == NUM_ADDR_BITS)  // NO bit was set
      begin
        stored_write_address[NUM_DATA_BITS - 1 : 0] = NUM_ADDR_BITS;
      end
      write_counter[5:0] = (write_counter[5:0] + 6'h01) & 6'h1F;
    end
  end
 
// Starting at the newest, search back to oldest to find if the word has been written
  reg    [NUM_DATA_BITS - 1 : 0] data_out;
  reg    [4:0] read_address;
 
  always @(posedge clk)
  begin
    if ((read_enable !== 1'b1) | ((^address[NUM_ADDR_BITS - 1 : 0]) === 1'bX))  // no read, return X's
    begin
      data_out[NUM_DATA_BITS - 1 : 0] = {NUM_DATA_BITS{1'bX}};
    end
    else
    if ((read_enable == 1'b1) && (write_enable == 1'b1))
    begin
      $display ("*** %m sram_for_debugging_sync cannot handle a read and a write at the same time");
      data_out[NUM_DATA_BITS - 1 : 0] = {NUM_DATA_BITS{1'bX}};
    end
    else if ((read_enable == 1'b1) && (write_enable == 1'b0))
    begin
      if ((address[NUM_ADDR_BITS - 1 : 0] >> (NUM_ADDR_BITS - 8)) == 8'hAA)  // read magic location, return Address Bit Number
      begin
        data_out[NUM_DATA_BITS - 1 : 0] = stored_write_address[NUM_DATA_BITS - 1 : 0];
      end
      else  // otherwise search history to see if the word has been written recently
      begin
        k = write_counter[5:0];
        for (l = k + 6'h1F;  // half way around, same as last minus 1;
             l >= k;  // write address not valid
             l = l - 1)
        begin
          read_address[4:0] = l;
          if (address[NUM_ADDR_BITS - 1 : 0] === address_storage[read_address[4:0]])
          begin
            data_out[NUM_DATA_BITS - 1 : 0] = data_storage[read_address[4:0]];
            l = k - 2;
          end
        end
        if (l == (k - 1))  // didn't find it at all!
        begin
          data_out[NUM_DATA_BITS - 1 : 0] = {NUM_DATA_BITS{1'bX}};
        end
      end
    end
  end
 
// synopsys translate_off
  initial
  begin
    if (NUM_ADDR_BITS < 8)
    begin
      $display ("*** Exiting because %m sram_for_debugging_sync Number of Address bits %d < 8",
                   NUM_ADDR_BITS);
      $finish;
    end
    if (NUM_DATA_BITS < 8)
    begin
      $display ("*** Exiting because %m sram_for_debugging_sync Number of Data bits %d < 8",
                   NUM_DATA_BITS);
      $finish;
    end
  end
// synopsys translate_on
endmodule
 
`define TEST_SRAM
`ifdef TEST_SRAM
module test_sram;
  reg    [11:0] address;
  reg    [8:0] data_in;
  reg     read_enable, write_enable;
  wire   [8:0] data_out;
  reg     clk;
 
  integer i;
 
  initial
  begin
    read_enable = 1'b0;
    write_enable = 1'b0;
    clk = 1'b0;
    for (i = 0; i < 12; i = i + 1)
    begin
      # 0;
      address[11:0] = (12'h001 << i);
      data_in[8:0] = i + 4;
      # 0; write_enable = 1'b1;
      # 0; clk = 1'b1;
      # 0; write_enable = 1'b0;
      # 0; clk = 1'b0;
      # 0;
      address[11:0] = 12'hAA0;
      # 0; read_enable = 1'b1;
      # 0; clk = 1'b1;
      # 0;
      if (data_out[8:0] !== i)
        $display ("*** Debug SRAM read failed %x %x", i, data_out[8:0]);
      # 0; read_enable = 1'b0;
      # 0; clk = 1'b0;
    end
 
    for (i = 0; i < 12; i = i + 1)
    begin
      # 0;
      address[11:0] = (12'h001 << i);
      # 0; read_enable = 1'b1;
      # 0; clk = 1'b1;
      # 0;
      if (data_out[8:0] !== (i + 4))
        $display ("*** Debug SRAM read failed %x %x", i, data_out[8:0]);
      # 0; read_enable = 1'b0;
      # 0; clk = 1'b0;
    end
 
    # 0;
    address[11:0] = 12'hXXX;
    # 0; read_enable = 1'b1;
    # 0; clk = 1'b1;
    # 0;
    if (data_out[8:0] !== 9'hXXX)
      $display ("*** Debug SRAM read failed %x %x", i, data_out[8:0]);
    # 0; read_enable = 1'b0;
    # 0; clk = 1'b0;
 
    # 0;
    address[11:0] = 12'h003;
    # 0; read_enable = 1'b1;
    # 0; clk = 1'b1;
    # 0;
    if (data_out[8:0] !== 9'hXXX)
      $display ("*** Debug SRAM read failed %x %x", i, data_out[8:0]);
    # 0; read_enable = 1'b0;
    # 0; clk = 1'b0;
 
    for (i = 0; i < 32; i = i + 1)
    begin
      # 0;
      address[11:0] = i;
      data_in[8:0] = i + 32;
      # 0; write_enable = 1'b1;
      # 0; clk = 1'b1;
      # 0; write_enable = 1'b0;
      # 0; clk = 1'b0;
    end
 
    for (i = 0; i < 32; i = i + 1)
    begin
      # 0;
      address[11:0] = i;
      # 0; read_enable = 1'b1;
      # 0; clk = 1'b1;
      # 0;
      if (data_out[8:0] !== (i + 32))
        $display ("*** Debug SRAM read failed %x %x", i, data_out[8:0]);
      # 0; read_enable = 1'b0;
      # 0; clk = 1'b0;
    end
 
  end
 
sram_for_debugging_sync
#(12,  // NUM_ADDR_BITS
   9   // NUM_DATA_BITS
 ) test_this_one (
  .data_out                   (data_out[8:0]),
  .data_in                    (data_in[8:0]),
  .address                    (address[11:0]),
  .read_enable                (read_enable),
  .write_enable               (write_enable),
  .clk                        (clk)
);
 
endmodule
`endif  // TEST_SRAM
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.