head 1.2;
access;
symbols;
locks; strict;
comment @# @;
1.2
date 2001.11.06.12.33.15; author bbeaver; state Exp;
branches;
next 1.1;
1.1
date 2001.10.02.06.16.52; author bbeaver; state Exp;
branches;
next ;
desc
@@
1.2
log
@no message
@
text
@//////////////////////////////////////////////////////////////////////
//// ////
//// sram_for_debugging_async #(NUM_ADDR_BITS, NUM_DATA_BITS) ////
//// ////
//// This file is part of the general opencores effort. ////
//// ////
//// ////
//// 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// $Id: sram_for_debugging_async.v,v 1.1 2001/10/02 05:23:27 Blue Beaver Exp $
//
// CVS Revision History
//
// $Log: sram_for_debugging_async.v,v $
// Revision 1.1 2001/10/02 05:23:27 Blue Beaver
// no message
//
// Revision 1.3 2001/09/27 08:05:43 Blue Beaver
// no message
//
// Revision 1.2 2001/09/26 09:46:20 Blue Beaver
// no message
//
// Revision 1.1 2001/09/25 10:49:34 Blue Beaver
// no message
//
`timescale 1ns/1ps
// instantiate as "sram_for_debugging_async #(NUM_ADDR_BITS, NUM_DATA_BITS) instance ()"
module sram_for_debugging_async (
data_out,
data_in,
address,
read_enable,
write_enable
);
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;
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 write_enable)
begin
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
// 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 @@(read_enable)
begin
if ((read_enable !== 1'b1) | ((^address[NUM_DATA_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
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_async Number of Address bits %d < 8",
NUM_ADDR_BITS);
$finish;
end
if (NUM_DATA_BITS < 8)
begin
$display ("*** Exiting because %m sram_for_debugging_async 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;
integer i;
initial
begin
read_enable = 1'b0;
write_enable = 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; write_enable = 1'b0;
# 0;
address[11:0] = 12'hAA0;
# 0; read_enable = 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;
end
for (i = 0; i < 12; i = i + 1)
begin
# 0;
address[11:0] = (12'h001 << i);
# 0; read_enable = 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;
end
# 0;
address[11:0] = 12'hXXX;
# 0; read_enable = 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;
address[11:0] = 12'h003;
# 0; read_enable = 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;
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; write_enable = 1'b0;
end
for (i = 0; i < 32; i = i + 1)
begin
# 0;
address[11:0] = i;
# 0; read_enable = 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;
end
end
sram_for_debugging_async
#(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)
);
endmodule
`endif // TEST_SRAM
@
1.1
log
@no message
@
text
@@