mirror of https://github.com/VLSIDA/OpenRAM.git
Updated Verilog to have multiport. Added 1rw,1rw/1r Verilog testbench.
This commit is contained in:
parent
f0ab155172
commit
5de7ff3773
|
|
@ -10,7 +10,7 @@ from vector import vector
|
|||
from pin_layout import pin_layout
|
||||
import lef
|
||||
|
||||
class layout(lef.lef):
|
||||
class layout():
|
||||
"""
|
||||
Class consisting of a set of objs and instances for a module
|
||||
This provides a set of useful generic types for hierarchy
|
||||
|
|
@ -21,7 +21,6 @@ class layout(lef.lef):
|
|||
"""
|
||||
|
||||
def __init__(self, name):
|
||||
lef.lef.__init__(self, ["metal1", "metal2", "metal3"])
|
||||
self.name = name
|
||||
self.width = None
|
||||
self.height = None
|
||||
|
|
|
|||
|
|
@ -2,9 +2,8 @@ import debug
|
|||
import re
|
||||
import os
|
||||
import math
|
||||
import verilog
|
||||
|
||||
class spice(verilog.verilog):
|
||||
class spice():
|
||||
"""
|
||||
This provides a set of useful generic types for hierarchy
|
||||
management. If a module is a custom designed cell, it will read from
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ from collections import defaultdict
|
|||
class lef:
|
||||
"""
|
||||
SRAM LEF Class open GDS file, read pins information, obstruction
|
||||
and write them to LEF file
|
||||
and write them to LEF file.
|
||||
This is inherited by the sram_base class.
|
||||
"""
|
||||
def __init__(self,layers):
|
||||
# LEF db units per micron
|
||||
|
|
|
|||
|
|
@ -1,60 +1,165 @@
|
|||
import debug
|
||||
|
||||
class verilog:
|
||||
""" Create a behavioral Verilog file for simulation."""
|
||||
|
||||
"""
|
||||
Create a behavioral Verilog file for simulation.
|
||||
This is inherited by the sram_base class.
|
||||
"""
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def verilog_write(self,verilog_name):
|
||||
""" Write a behavioral Verilog model. """
|
||||
|
||||
self.vf = open(verilog_name, "w")
|
||||
|
||||
self.vf.write("// OpenRAM SRAM model\n")
|
||||
self.vf.write("// Words: {0}\n".format(self.num_words))
|
||||
self.vf.write("// Word size: {0}\n\n".format(self.word_size))
|
||||
|
||||
self.vf.write("module {0}(DATA,ADDR,CSb,WEb,OEb,clk);\n".format(self.name))
|
||||
self.vf.write("\n")
|
||||
|
||||
self.vf.write("module {0}(\n".format(self.name))
|
||||
for port in self.all_ports:
|
||||
if port in self.readwrite_ports:
|
||||
self.vf.write("// Port {0}: RW\n".format(port))
|
||||
elif port in self.read_ports:
|
||||
self.vf.write("// Port {0}: R\n".format(port))
|
||||
elif port in self.write_ports:
|
||||
self.vf.write("// Port {0}: W\n".format(port))
|
||||
if port in self.readwrite_ports:
|
||||
self.vf.write(" clk{0},csb{0},web{0},ADDR{0},DIN{0},DOUT{0}".format(port))
|
||||
elif port in self.write_ports:
|
||||
self.vf.write(" clk{0},csb{0},ADDR{0},DIN{0}".format(port))
|
||||
elif port in self.read_ports:
|
||||
self.vf.write(" clk{0},csb{0},ADDR{0},DOUT{0}".format(port))
|
||||
# Continue for every port on a new line
|
||||
if port != self.all_ports[-1]:
|
||||
self.vf.write(",\n")
|
||||
self.vf.write("\n );\n\n")
|
||||
|
||||
self.vf.write(" parameter DATA_WIDTH = {0} ;\n".format(self.word_size))
|
||||
self.vf.write(" parameter ADDR_WIDTH = {0} ;\n".format(self.addr_size))
|
||||
self.vf.write(" parameter RAM_DEPTH = 1 << ADDR_WIDTH;\n")
|
||||
self.vf.write(" // FIXME: This delay is arbitrary.\n")
|
||||
self.vf.write(" parameter DELAY = 3 ;\n")
|
||||
self.vf.write("\n")
|
||||
self.vf.write(" inout [DATA_WIDTH-1:0] DATA;\n")
|
||||
self.vf.write(" input [ADDR_WIDTH-1:0] ADDR;\n")
|
||||
self.vf.write(" input CSb; // active low chip select\n")
|
||||
self.vf.write(" input WEb; // active low write control\n")
|
||||
self.vf.write(" input OEb; // active output enable\n")
|
||||
self.vf.write(" input clk; // clock\n")
|
||||
self.vf.write("\n")
|
||||
self.vf.write(" reg [DATA_WIDTH-1:0] data_out ;\n")
|
||||
self.vf.write(" reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];\n")
|
||||
|
||||
for port in self.all_ports:
|
||||
self.add_inputs_outputs(port)
|
||||
|
||||
self.vf.write("\n")
|
||||
self.vf.write(" // Tri-State Buffer control\n")
|
||||
self.vf.write(" // output : When WEb = 1, oeb = 0, csb = 0\n")
|
||||
self.vf.write(" assign DATA = (!CSb && !OEb && WEb) ? data_out : {0}'bz;\n".format(self.word_size))
|
||||
self.vf.write("\n")
|
||||
self.vf.write(" // Memory Write Block\n")
|
||||
self.vf.write(" // Write Operation : When WEb = 0, CSb = 0\n")
|
||||
self.vf.write(" always @ (posedge clk)\n")
|
||||
self.vf.write(" begin : MEM_WRITE\n")
|
||||
self.vf.write(" if ( !CSb && !WEb ) begin\n")
|
||||
self.vf.write(" mem[ADDR] = DATA;\n")
|
||||
self.vf.write(" $display($time,\" Writing %m ABUS=%b DATA=%b\",ADDR,DATA);\n")
|
||||
self.vf.write(" end\n")
|
||||
self.vf.write(" end\n\n")
|
||||
self.vf.write("\n")
|
||||
self.vf.write(" // Memory Read Block\n")
|
||||
self.vf.write(" // Read Operation : When WEb = 1, CSb = 0\n")
|
||||
self.vf.write(" always @ (posedge clk)\n")
|
||||
self.vf.write(" begin : MEM_READ\n")
|
||||
self.vf.write(" if (!CSb && WEb) begin\n")
|
||||
self.vf.write(" data_out <= #(DELAY) mem[ADDR];\n")
|
||||
self.vf.write(" $display($time,\" Reading %m ABUS=%b DATA=%b\",ADDR,mem[ADDR]);\n")
|
||||
self.vf.write(" end\n")
|
||||
self.vf.write(" end\n")
|
||||
|
||||
for port in self.all_ports:
|
||||
self.register_inputs(port)
|
||||
|
||||
# This is the memory array itself
|
||||
self.vf.write("reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];\n")
|
||||
|
||||
for port in self.all_ports:
|
||||
if port in self.write_ports:
|
||||
self.add_write_block(port)
|
||||
if port in self.read_ports:
|
||||
self.add_read_block(port)
|
||||
|
||||
self.vf.write("\n")
|
||||
self.vf.write("endmodule\n")
|
||||
|
||||
|
||||
self.vf.close()
|
||||
|
||||
|
||||
def register_inputs(self, port):
|
||||
"""
|
||||
Register the control signal, address and data inputs.
|
||||
"""
|
||||
self.add_regs(port)
|
||||
self.add_flops(port)
|
||||
|
||||
def add_regs(self, port):
|
||||
"""
|
||||
Create the input regs for the given port.
|
||||
"""
|
||||
self.vf.write(" reg csb{0}_reg;\n".format(port))
|
||||
if port in self.readwrite_ports:
|
||||
self.vf.write(" reg web{0}_reg;\n".format(port))
|
||||
self.vf.write(" reg [ADDR_WIDTH-1:0] ADDR{0}_reg;\n".format(port))
|
||||
if port in self.write_ports:
|
||||
self.vf.write(" reg [DATA_WIDTH-1:0] DIN{0}_reg;\n".format(port))
|
||||
if port in self.read_ports:
|
||||
self.vf.write(" reg [DATA_WIDTH-1:0] DOUT{0};\n".format(port))
|
||||
|
||||
def add_flops(self, port):
|
||||
"""
|
||||
Add the flop behavior logic for a port.
|
||||
"""
|
||||
self.vf.write("\n")
|
||||
self.vf.write(" // All inputs are registers\n")
|
||||
self.vf.write(" always @(posedge clk{0})\n".format(port))
|
||||
self.vf.write(" begin\n")
|
||||
self.vf.write(" csb{0}_reg = csb{0};\n".format(port))
|
||||
if port in self.readwrite_ports:
|
||||
self.vf.write(" web{0}_reg = web{0};\n".format(port))
|
||||
self.vf.write(" ADDR{0}_reg = ADDR{0};\n".format(port))
|
||||
if port in self.write_ports:
|
||||
self.vf.write(" DIN{0}_reg = DIN{0};\n".format(port))
|
||||
if port in self.read_ports:
|
||||
self.vf.write(" DOUT{0} = {1}'bx;\n".format(port,self.word_size))
|
||||
if port in self.readwrite_ports:
|
||||
self.vf.write(" if ( !csb{0}_reg && web{0}_reg ) \n".format(port))
|
||||
self.vf.write(" $display($time,\" Reading %m ADDR{0}=%b DOUT{0}=%b\",ADDR{0}_reg,mem[ADDR{0}_reg]);\n".format(port))
|
||||
elif port in self.read_ports:
|
||||
self.vf.write(" if ( !csb{0}_reg ) \n".format(port))
|
||||
self.vf.write(" $display($time,\" Reading %m ADDR{0}=%b DOUT{0}=%b\",ADDR{0}_reg,mem[ADDR{0}_reg]);\n".format(port))
|
||||
|
||||
if port in self.readwrite_ports:
|
||||
self.vf.write(" if ( !csb{0}_reg && !web{0}_reg )\n".format(port))
|
||||
self.vf.write(" $display($time,\" Writing %m ADDR{0}=%b DIN{0}=%b\",ADDR{0}_reg,DIN{0}_reg);\n".format(port))
|
||||
elif port in self.write_ports:
|
||||
self.vf.write(" if ( !csb{0}_reg )\n".format(port))
|
||||
self.vf.write(" $display($time,\" Writing %m ADDR{0}=%b DIN{0}=%b\",ADDR{0}_reg,DIN{0}_reg);\n".format(port))
|
||||
self.vf.write(" end\n\n")
|
||||
|
||||
|
||||
def add_inputs_outputs(self, port):
|
||||
"""
|
||||
Add the module input and output declaration for a port.
|
||||
"""
|
||||
self.vf.write(" input clk{0}; // clock\n".format(port))
|
||||
self.vf.write(" input csb{0}; // active low chip select\n".format(port))
|
||||
if port in self.readwrite_ports:
|
||||
self.vf.write(" input web{0}; // active low write control\n".format(port))
|
||||
self.vf.write(" input [ADDR_WIDTH-1:0] ADDR{0};\n".format(port))
|
||||
if port in self.write_ports:
|
||||
self.vf.write(" input [DATA_WIDTH-1:0] DIN{0};\n".format(port))
|
||||
if port in self.read_ports:
|
||||
self.vf.write(" output [DATA_WIDTH-1:0] DOUT{0};\n".format(port))
|
||||
|
||||
def add_write_block(self, port):
|
||||
"""
|
||||
Add a write port block. Multiple simultaneous writes to the same address
|
||||
have arbitrary priority and are not allowed.
|
||||
"""
|
||||
self.vf.write("\n")
|
||||
self.vf.write(" // Memory Write Block Port {0}\n".format(port))
|
||||
self.vf.write(" // Write Operation : When web{0} = 0, csb{0} = 0\n".format(port))
|
||||
self.vf.write(" always @ (negedge clk{0})\n".format(port))
|
||||
self.vf.write(" begin : MEM_WRITE{0}\n".format(port))
|
||||
if port in self.readwrite_ports:
|
||||
self.vf.write(" if ( !csb{0}_reg && !web{0}_reg )\n".format(port))
|
||||
else:
|
||||
self.vf.write(" if (!csb{0}_reg)\n".format(port))
|
||||
self.vf.write(" mem[ADDR{0}_reg] = DIN{0}_reg;\n".format(port))
|
||||
self.vf.write(" end\n")
|
||||
|
||||
def add_read_block(self, port):
|
||||
"""
|
||||
Add a read port block.
|
||||
"""
|
||||
self.vf.write("\n")
|
||||
self.vf.write(" // Memory Read Block Port {0}\n".format(port))
|
||||
self.vf.write(" // Read Operation : When web{0} = 1, csb{0} = 0\n".format(port))
|
||||
self.vf.write(" always @ (negedge clk{0})\n".format(port))
|
||||
self.vf.write(" begin : MEM_READ{0}\n".format(port))
|
||||
if port in self.readwrite_ports:
|
||||
self.vf.write(" if (!csb{0}_reg && web{0}_reg)\n".format(port))
|
||||
else:
|
||||
self.vf.write(" if (!csb{0}_reg)\n".format(port))
|
||||
self.vf.write(" DOUT{0} <= #(DELAY) mem[ADDR{0}_reg];\n".format(port))
|
||||
self.vf.write(" end\n")
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
word_size = 8
|
||||
num_words = 128
|
||||
|
||||
tech_name = "scn4m_subm"
|
||||
process_corners = ["TT"]
|
||||
supply_voltages = [ 5.0 ]
|
||||
temperatures = [ 25 ]
|
||||
|
||||
output_path = "temp"
|
||||
output_name = "sram_{0}_{1}_{2}".format(word_size,num_words,tech_name)
|
||||
|
||||
drc_name = "magic"
|
||||
lvs_name = "netgen"
|
||||
pex_name = "magic"
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
word_size = 2
|
||||
num_words = 16
|
||||
|
||||
bitcell = "bitcell_1rw_1r"
|
||||
replica_bitcell = "replica_bitcell_1rw_1r"
|
||||
num_rw_ports = 1
|
||||
num_r_ports = 1
|
||||
num_w_ports = 0
|
||||
|
||||
tech_name = "scn4m_subm"
|
||||
process_corners = ["TT"]
|
||||
supply_voltages = [5.0]
|
||||
temperatures = [25]
|
||||
|
||||
output_path = "temp"
|
||||
output_name = "sram_1rw_1r_{0}_{1}_{2}".format(word_size,num_words,tech_name)
|
||||
|
||||
drc_name = "magic"
|
||||
lvs_name = "netgen"
|
||||
pex_name = "magic"
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
word_size = 16
|
||||
num_words = 256
|
||||
|
||||
tech_name = "scn4m_subm"
|
||||
process_corners = ["TT"]
|
||||
supply_voltages = [ 3.3 ]
|
||||
temperatures = [ 25 ]
|
||||
|
||||
output_path = "temp"
|
||||
output_name = "sram_{0}_{1}_{2}".format(word_size,num_words,tech_name)
|
||||
|
||||
drc_name = "magic"
|
||||
lvs_name = "netgen"
|
||||
pex_name = "magic"
|
||||
|
|
@ -50,7 +50,7 @@ print("Words per row: {}".format(c.words_per_row))
|
|||
output_extensions = ["sp","v","lib","py","html"]
|
||||
if not OPTS.netlist_only:
|
||||
output_extensions.extend(["gds","lef"])
|
||||
output_files = ["{0}.{1}".format(OPTS.output_name,x) for x in output_extensions]
|
||||
output_files = ["{0}{1}.{2}".format(OPTS.output_path,OPTS.output_name,x) for x in output_extensions]
|
||||
print("Output files are: ")
|
||||
print(*output_files,sep="\n")
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,9 @@ class sram():
|
|||
def sp_write(self,name):
|
||||
self.s.sp_write(name)
|
||||
|
||||
def lef_write(self,name):
|
||||
self.s.lef_write(name)
|
||||
|
||||
def gds_write(self,name):
|
||||
self.s.gds_write(name)
|
||||
|
||||
|
|
@ -63,21 +66,21 @@ class sram():
|
|||
start_time = datetime.datetime.now()
|
||||
gdsname = OPTS.output_path + self.s.name + ".gds"
|
||||
print("GDS: Writing to {0}".format(gdsname))
|
||||
self.s.gds_write(gdsname)
|
||||
self.gds_write(gdsname)
|
||||
print_time("GDS", datetime.datetime.now(), start_time)
|
||||
|
||||
# Create a LEF physical model
|
||||
start_time = datetime.datetime.now()
|
||||
lefname = OPTS.output_path + self.s.name + ".lef"
|
||||
print("LEF: Writing to {0}".format(lefname))
|
||||
self.s.lef_write(lefname)
|
||||
self.lef_write(lefname)
|
||||
print_time("LEF", datetime.datetime.now(), start_time)
|
||||
|
||||
# Save the spice file
|
||||
start_time = datetime.datetime.now()
|
||||
spname = OPTS.output_path + self.s.name + ".sp"
|
||||
print("SP: Writing to {0}".format(spname))
|
||||
self.s.sp_write(spname)
|
||||
self.sp_write(spname)
|
||||
print_time("Spice writing", datetime.datetime.now(), start_time)
|
||||
|
||||
# Save the extracted spice file
|
||||
|
|
@ -126,5 +129,5 @@ class sram():
|
|||
start_time = datetime.datetime.now()
|
||||
vname = OPTS.output_path + self.s.name + ".v"
|
||||
print("Verilog: Writing to {0}".format(vname))
|
||||
self.s.verilog_write(vname)
|
||||
self.verilog_write(vname)
|
||||
print_time("Verilog", datetime.datetime.now(), start_time)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class sram_1bank(sram_base):
|
|||
"""
|
||||
def __init__(self, name, sram_config):
|
||||
sram_base.__init__(self, name, sram_config)
|
||||
|
||||
|
||||
def create_modules(self):
|
||||
"""
|
||||
This adds the modules for a single bank SRAM with control
|
||||
|
|
|
|||
|
|
@ -8,14 +8,18 @@ from vector import vector
|
|||
from globals import OPTS, print_time
|
||||
import logical_effort
|
||||
from design import design
|
||||
|
||||
class sram_base(design):
|
||||
from verilog import verilog
|
||||
from lef import lef
|
||||
|
||||
class sram_base(design, verilog, lef):
|
||||
"""
|
||||
Dynamically generated SRAM by connecting banks to control logic. The
|
||||
number of banks should be 1 , 2 or 4
|
||||
"""
|
||||
def __init__(self, name, sram_config):
|
||||
design.__init__(self, name)
|
||||
lef.__init__(self, ["metal1", "metal2", "metal3"])
|
||||
verilog.__init__(self)
|
||||
|
||||
self.sram_config = sram_config
|
||||
sram_config.set_local_config(self)
|
||||
|
|
@ -531,4 +535,4 @@ class sram_base(design):
|
|||
return bank_sen_cin
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,143 @@
|
|||
`define assert(signal, value) \
|
||||
if (!(signal === value)) begin \
|
||||
$display("ASSERTION FAILED in %m: signal != value"); \
|
||||
$finish;\
|
||||
end
|
||||
|
||||
module sram_1rw_1r_tb;
|
||||
reg clk;
|
||||
|
||||
// 1rw port
|
||||
reg [3:0] addr0;
|
||||
reg [1:0] din0;
|
||||
reg csb0;
|
||||
reg web0;
|
||||
wire [1:0] dout0;
|
||||
|
||||
// 1r port
|
||||
reg [3:0] addr1;
|
||||
reg csb1;
|
||||
wire [1:0] dout1;
|
||||
|
||||
sram_1rw_1r_2_16_scn4m_subm U0 (.DIN0(din0),
|
||||
.DOUT0(dout0),
|
||||
.ADDR0(addr0),
|
||||
.csb0(csb0),
|
||||
.web0(web0),
|
||||
.clk0(clk),
|
||||
.DOUT1(dout1),
|
||||
.ADDR1(addr1),
|
||||
.csb1(csb1),
|
||||
.clk1(clk)
|
||||
);
|
||||
|
||||
|
||||
initial
|
||||
begin
|
||||
|
||||
//$monitor("%g addr0=%b din0=%b dout0=%b addr1=%b dout1=%b",
|
||||
// $time, addr0, din0, dout0, addr1, dout1);
|
||||
|
||||
clk = 1;
|
||||
csb0 = 1;
|
||||
web0 = 1;
|
||||
addr0 = 0;
|
||||
din0 = 0;
|
||||
|
||||
csb1 = 1;
|
||||
addr1 = 0;
|
||||
|
||||
// write
|
||||
#10 din0=2'b10;
|
||||
addr0=4'h1;
|
||||
web0 = 0;
|
||||
csb0 = 0;
|
||||
// nop
|
||||
csb1 = 1;
|
||||
addr1 = 0;
|
||||
|
||||
// write another
|
||||
#10 din0=2'b01;
|
||||
addr0=4'hC;
|
||||
web0 = 0;
|
||||
csb0 = 0;
|
||||
// read last
|
||||
csb1 = 0;
|
||||
addr1 = 4'h1;
|
||||
|
||||
#10 `assert(dout1, 2'b10)
|
||||
|
||||
// read undefined
|
||||
din0=2'b11;
|
||||
addr0=4'h0;
|
||||
web0 = 1;
|
||||
csb0 = 0;
|
||||
// read another
|
||||
csb1 = 0;
|
||||
addr1 = 4'hC;
|
||||
|
||||
#10 `assert(dout0, 2'bxx)
|
||||
`assert(dout1, 2'b01)
|
||||
|
||||
// read defined
|
||||
din0=2'b11;
|
||||
addr0=4'hC;
|
||||
web0 = 1;
|
||||
csb0 = 0;
|
||||
// read undefined
|
||||
csb1 = 0;
|
||||
addr1 = 4'hD;
|
||||
|
||||
#10 `assert(dout0, 2'b01)
|
||||
`assert(dout1, 2'bxx)
|
||||
|
||||
// write another
|
||||
din0=2'b11;
|
||||
addr0=4'hA;
|
||||
web0 = 0;
|
||||
csb0 = 0;
|
||||
// read the feedthrough value
|
||||
csb1 = 0;
|
||||
addr1 = 4'hA;
|
||||
|
||||
#10 `assert(dout1, 2'b11)
|
||||
|
||||
// read defined
|
||||
din0=2'b11;
|
||||
addr0=4'h1;
|
||||
web0 = 1;
|
||||
csb0 = 0;
|
||||
// read old value
|
||||
csb1 = 0;
|
||||
addr1 = 4'h1;
|
||||
|
||||
#10 `assert(dout0, 2'b10)
|
||||
`assert(dout1, 2'b10)
|
||||
|
||||
// read defined
|
||||
din0=2'b11;
|
||||
addr0=4'hA;
|
||||
web0 = 1;
|
||||
csb0 = 0;
|
||||
// dual read
|
||||
csb1 = 0;
|
||||
addr1 = 4'hA;
|
||||
#10 `assert(dout0, 2'b11)
|
||||
`assert(dout1, 2'b11)
|
||||
|
||||
// read undefined
|
||||
din0=2'b11;
|
||||
addr0=4'h0;
|
||||
web0 = 1;
|
||||
csb0 = 0;
|
||||
|
||||
#10 `assert(dout0, 2'bxx)
|
||||
|
||||
#10 $finish;
|
||||
|
||||
end
|
||||
|
||||
always
|
||||
#5 clk = !clk;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
`define assert(signal, value) \
|
||||
if (!(signal === value)) begin \
|
||||
$display("ASSERTION FAILED in %m: signal != value"); \
|
||||
$finish;\
|
||||
end
|
||||
|
||||
module sram_1rw_tb;
|
||||
reg clk;
|
||||
|
||||
reg [3:0] addr0;
|
||||
reg [1:0] din0;
|
||||
reg csb0;
|
||||
reg web0;
|
||||
wire [1:0] dout0;
|
||||
|
||||
sram_2_16_scn4m_subm U0 (.DIN0(din0),
|
||||
.DOUT0(dout0),
|
||||
.ADDR0(addr0),
|
||||
.csb0(csb0),
|
||||
.web0(web0),
|
||||
.clk0(clk)
|
||||
);
|
||||
|
||||
|
||||
initial
|
||||
begin
|
||||
|
||||
//$monitor("%g addr0=%b din0=%b dout0=%b",
|
||||
// $time, addr0, din0, dout0);
|
||||
|
||||
|
||||
clk = 1;
|
||||
csb0 = 1;
|
||||
web0 = 1;
|
||||
addr0 = 0;
|
||||
din0 = 0;
|
||||
|
||||
// write
|
||||
#10 din0=2'b10;
|
||||
addr0=4'h1;
|
||||
web0 = 0;
|
||||
csb0 = 0;
|
||||
|
||||
// write another
|
||||
#10 din0=2'b01;
|
||||
addr0=4'hC;
|
||||
web0 = 0;
|
||||
csb0 = 0;
|
||||
|
||||
// read undefined
|
||||
#10 din0=2'b11;
|
||||
addr0=4'h0;
|
||||
web0 = 1;
|
||||
csb0 = 0;
|
||||
|
||||
#10 `assert(dout0, 2'bxx)
|
||||
|
||||
// read defined
|
||||
din0=2'b11;
|
||||
addr0=4'hC;
|
||||
web0 = 1;
|
||||
csb0 = 0;
|
||||
|
||||
#10 `assert(dout0, 2'b01)
|
||||
|
||||
// write another
|
||||
din0=2'b11;
|
||||
addr0=4'hA;
|
||||
web0 = 0;
|
||||
csb0 = 0;
|
||||
|
||||
// read defined
|
||||
#10 din0=2'b11;
|
||||
addr0=4'h1;
|
||||
web0 = 1;
|
||||
csb0 = 0;
|
||||
|
||||
#10 `assert(dout0, 2'b10)
|
||||
|
||||
// read defined
|
||||
din0=2'b11;
|
||||
addr0=4'hA;
|
||||
web0 = 1;
|
||||
csb0 = 0;
|
||||
|
||||
#10 `assert(dout0, 2'b11)
|
||||
|
||||
// read undefined
|
||||
din0=2'b11;
|
||||
addr0=4'h0;
|
||||
web0 = 1;
|
||||
csb0 = 0;
|
||||
|
||||
#10 `assert(dout0, 2'bxx)
|
||||
|
||||
#10 $finish;
|
||||
|
||||
end
|
||||
|
||||
always
|
||||
#5 clk = !clk;
|
||||
|
||||
endmodule
|
||||
Loading…
Reference in New Issue