How modeling static RAM in Verilog - Page 1
Forum section: electronics / general

author: caius
author_rank: Regular Contributor
timestamp: October 31, 2024, 10:11:49 pm
content: Hi all,it came the time for me to model a static RAM in Verilog.I'm uncertain if using registers or block, the RAM must be static therefore asynchronous.I attach the schematics (one RAM must be 256X8, the other 128X8)Thanks in advance for any help or advice.P.S.The models will run on MAX10 FPGA.

author: woofy
author_rank: Frequent Contributor
timestamp: November 01, 2024, 11:52:44 am
content: Quote from: caius on October 31, 2024, 10:11:49 pmstatic rams can be synchronous, and when inferring an fpga's built in ram blocks, usually are.I've not used the max10, but the ice40 example below should be very similar.Code:module DataRam (din, write_en, waddr, raddr, clk, dout);parameter addr_width = 10;parameter data_width = 8;input [addr_width-1:0] waddr, raddr;input [data_width-1:0] din;input write_en, clk;output reg [data_width-1:0] dout;reg [data_width-1:0] mem [(1<<addr_width)-1:0];initial begin$readmemh("dta_data", mem);// dta_data - the initialised 8-bit ramendalways @(posedge clk) // Write memory.beginif (write_en)mem <= din; // Using write address bus.endalways @(posedge clk) // Read memory.begindout <= mem; // Using read address bus.endendmodule

author: nctnico
author_rank: Super Contributor
timestamp: November 01, 2024, 03:10:04 pm
content: Generally speaking: if you infer asynchronous RAM, the synthesizer will be forced to use flipflops and/or LUTS. With synchronous RAM, the synthesizer can choose what is most efficient (synchronous block ram or use LUTs / flipflops anyway).

author: caius
author_rank: Regular Contributor
timestamp: November 01, 2024, 06:22:47 pm
content: Thanks for answers.I found this module for a 2K X 8Bit RAM, maybe I can adapt it for my needs :Code:module ram#(parameter addr_width=12,parameter data_width=8)(input clk,input [addr_width-1:0] addr,input [data_width-1:0] din,output [data_width-1:0] q,input rd_n,input wr_n,input ce_n);reg [data_width-1:0] data;reg [data_width-1:0] mem[(1<<addr_width)-1:0];assign q = ~ce_n ? data : 0;always @(posedge clk) beginif (~rd_n) data <= mem;if (~wr_n & ~ce_n) mem <= din;endendmodule

author: BrianHG
author_rank: Super Contributor
timestamp: November 01, 2024, 09:35:36 pm
content: You didn't set an optional attribute for your:Code:reg [data_width-1:0] mem[(1<<addr_width)-1:0];Read here:https://www.intel.com/content/www/us/en/programmable/quartushelp/17.0/hdl/vlog/vlog_file_dir_ram.htmor a default init file:Read here:https://www.intel.com/content/www/us/en/programmable/quartushelp/17.0/hdl/vlog/vlog_file_dir_ram_init.htmor default power-up initialization value like:Code:reg [data_width-1:0] mem[(1<<addr_width)-1:0] = '{default:'0} ;or in-line coded assigned init values like here:https://github.com/BrianHGinc/BHG_I2C_init_RS232_debugger/blob/8a607f0d0aebf0e0bc151308c545c21822d9936b/hdl/BHG_I2C_init_RS232_debugger.sv#L495

author: caius
author_rank: Regular Contributor
timestamp: November 02, 2024, 04:22:32 pm
content: Quote from: BrianHG on November 01, 2024, 09:35:36 pmIs it important to fill the RAM with an initial contents?I found this other model :Code:module SRAM_sync #(parameter DATA_WIDTH = 8, ADDR_WIDTH = 8)(input wire clk,input wire [ADDR_WIDTH-1:0] ADDR,input wire [DATA_WIDTH-1:0] DATA,(* direct_enable = 1 *) input wire CEn,input wire OEn,input wire WEn,output reg [DATA_WIDTH-1:0] Q);reg [DATA_WIDTH-1:0] mem[0:(2**ADDR_WIDTH)-1];reg [DATA_WIDTH-1:0] data_out;always @(posedge clk) beginif(!CEn) beginif(!OEn) beginQ <= mem;endendif(!CEn) beginif(!WEn) beginmem <= DATA;endendendendmodule

author: BrianHG
author_rank: Super Contributor
timestamp: November 02, 2024, 06:38:20 pm
content: Quote from: caius on November 02, 2024, 04:22:32 pmReasons for filling the ram or at least adding the = '{default:'0}...When simulating your design, without anything, or even at least the ='{default:'0}, until you write to any memory address, all reads to non written addresses will return an 'X' or undefined instead of a 0.Unlike when you simulate your design, by default, un-assigned memory in an FPGA will power-up default to all 0.Note that filling your memory with initial power-up data usually will not consume any additional resources in your FPGA unless the memory is stored in logic cells and you are trying to do something unusually special.

author: BrianHG
author_rank: Super Contributor
timestamp: November 02, 2024, 06:46:01 pm
content: See my /*************************** for changing your memory into a proper tri-state output enable.Quote from: caius on November 01, 2024, 06:22:47 pm

author: caius
author_rank: Regular Contributor
timestamp: November 02, 2024, 10:03:59 pm
content: Quote from: BrianHG on November 02, 2024, 06:46:01 pmThanks.Since I'm using Quartus schematics I'm having some troubles in wiring the busses.How can I change the RAM code in order to split the bus into singe address and data pins?

author: BrianHG
author_rank: Super Contributor
timestamp: November 02, 2024, 10:53:46 pm
content: Quote from: caius on November 02, 2024, 10:03:59 pmPlease show me what you mean.You already have a separate data and address bus.Are you using the block schematics?(It is good practice to learn how to do everything in HDL, however I understand if you are trying to make a cheap fast 2-3 component/module design to emulate a TTL schematic.)Also, it is goo practice on how to use a simulator.

author: caius
author_rank: Regular Contributor
timestamp: November 02, 2024, 11:48:58 pm
content: Quote from: BrianHG on November 02, 2024, 10:53:46 pmYes, I'm using block schematics in Quartus trying to emulate a TTL schematics.I would like to have the RAM symbol with individual pins (for example, address bus as A0, A1, A2, A3, A4 etc.Same for DATA input and output).Just like the attached symbol.P.S.Dumb question : I know data pins are bidirectional but why to have in Verilog RAM module a separate bus for data input and data output?It would possible to declare them as 'inout' and have only a set of pins like attached symbol?

author: BrianHG
author_rank: Super Contributor
timestamp: November 03, 2024, 12:02:23 am
content: Quote from: caius on November 02, 2024, 11:48:58 pmIn quartus schematic, you just wire the address or data bus as ' data[7..0] ', then you can use wires where ever you like data, data, ect.Yes, if I remember correctly as it has been like 15 years, quartus in the block diagrams use the double period instead of the colon.The hard way would be to draw your own sub-schematic of the ram chip, wiring individual input pins and output pins to the .v code, then generate a block diagram symbol from that schematic perfectly matching your picture.As for the separate in and out for the data, it is the way it operates in the FPGA and runs much faster (like 3x) than using a single tri-state IO bus for the data. You can also now write data while simultaneously reading data with a separate data in and data out.Yes, you can modify your .v code to use 1 tristate data bus for reading and writing if you want to perfectly simulate a static ram chip.

author: caius
author_rank: Regular Contributor
timestamp: November 04, 2024, 11:43:23 pm
content: Thanks for reply.I'm using this RAM model for a 128x8-bit :Code:module ram128#(parameter addr_width=7,parameter data_width=8)(input clk,input [addr_width-1:0] addr,input [data_width-1:0] din,inout [data_width-1:0] q,input rd_n,input wr_n,input ce_n);reg [data_width-1:0] data;reg [data_width-1:0] mem[(1<<addr_width)-1:0];assign q = ~ce_n ? data : {data_width{1'bz}};always @(posedge clk) beginif (~rd_n) data <= mem;if (~wr_n & ~ce_n) mem <= din;endAnd this for a 256x8-bit :Code:module ram_#(parameter addr_width=8,parameter data_width=8)(input clk,input [addr_width-1:0] addr,input [data_width-1:0] din,inout [data_width-1:0] q,input rd_n,input wr_n,input ce_n);reg [data_width-1:0] data;reg [data_width-1:0] mem[(1<<addr_width)-1:0];assign q = ~ce_n ? data : {data_width{1'bz}};always @(posedge clk) beginif (~rd_n) data <= mem;if (~wr_n & ~ce_n) mem <= din;endendmoduleI implemented these modules in the whole block schematics under Quartus (translated from TTL schematics).When I try to do a compile I get the errors in the attached log.I attach also a the snippet of TTL schematics that I'm trying to simulate in Quartus.Thanks in advance for any help or suggestion.

author: BrianHG
author_rank: Super Contributor
timestamp: November 05, 2024, 12:54:14 am
content: Show us your quartus schematic with wiring to the IO pins.

author: caius
author_rank: Regular Contributor
timestamp: November 05, 2024, 09:31:25 am
content: Quote from: BrianHG on November 05, 2024, 12:54:14 amHere attached the Quartus block schematics with MAX10 IO assignement (sorry it's a big messy one ) and original TTL schematics.

author: xvr
author_rank: Frequent Contributor
timestamp: November 05, 2024, 07:06:27 pm
content: FPGA do not have tristate buffers internally. Quartus try to convert your RAM data bus from tristate to switches, but unsuccessfully. Did you really need tristate/bidirectional data bus on RAM module?

author: caius
author_rank: Regular Contributor
timestamp: November 05, 2024, 09:17:22 pm
content: Quote from: xvr on November 05, 2024, 07:06:27 pmI think I need bidirectional data bus on RAM modules since original design have it.

author: BrianHG
author_rank: Super Contributor
timestamp: November 06, 2024, 02:13:36 am
content: QuoteTake a look at your schematic.Both ram chips read enables are wired together.Ok, like said above, you cannot do tristate busses inside the FPGA.Change your ram code from:Code:inout [data_width-1:0] q,...assign q = ~ce_n ? data : {data_width{1'bz}};to:Code:output [data_width-1:0] q,...assign q = ~ce_n ? data : {data_width{1'b0}};and use an 'OR' gate on the output busses to merge the 'Q' outputs to a single output.Also, the schematic might not work right unless you design clock-less static memory modules instead of synchronous clocked memory modules. That is unless you mode the clocked address and data buffers from the TTL components to inside your verilog ram modules. The other choice is to use the PLL to 2x the speed of your source clock and run the ram at 2x clock frequency.(Also, next time you try a project like this, maybe use multiple sub schematic pages like your source TTL schematic, and have a 'top' hierarchy schematic wiring those sup pages together and also wire to the selected FPGA IO pins.)

author: caius
author_rank: Regular Contributor
timestamp: November 06, 2024, 10:32:37 am
content: Thanks for reply.I changed the RAM code as suggested and put an OR gate as attached screenshot but I get errors on Quartus compiling (log attached)I forgot to say that I have a Verilog code (not made by me) of the original TTL schematics but it has still issue after I fixed some with the use of a PLL (thanks again BrianHG for the precious help!).I covered this in another thread here :https://www.eevblog.com/forum/fpga/help-on-translate-schematics-to-verilog/I attach again the Verilog code, I think the issue is related to the simulated RAMs (the author used registers instead of blocks, maybe they are asynchronous and must synchronous instead)

author: xvr
author_rank: Frequent Contributor
timestamp: November 06, 2024, 11:05:50 am
content: This Verilog code will not work. Direct implementation of discret logic into FPGA also will not work (almost everytime). That kind of design violate synchronous design principles. All synchronization signals generated inside FPGA logic will be very prone to glitches. In discrete logic design these glitches will be suppressed by limited speed of logic and by wire capacitance. This is not the case for FPGA - here all glitchess will affect triggers.

author: caius
author_rank: Regular Contributor
timestamp: November 06, 2024, 11:37:06 am
content: Quote from: xvr on November 06, 2024, 11:05:50 amWell, with some tweaking (implementing a PLL and a 4.7K resistor in series to main clock) I got the design mostly working.I remind you all the original TTL schematics are from a custom IC used on some arcade PCBs from '80, I desgined a replacement of this custom IC based on a MAX10 FPGA running the above Verilog code.I said 'mostly' because there are still issue on a specific arcade board, some garbage graphics on screen that I 'm unable to get rid of.For this reason I thought to translate the original TTL schematics to Quartus block schematics to see if this may lead to some improvement.

author: xvr
author_rank: Frequent Contributor
timestamp: November 06, 2024, 11:45:46 am
content: 'Garbage graphics ' is a result of asynchronous design. It can't be removed by some block changing. The only one way to get rid of them is to reimplement original schematic in synchronous manner

author: caius
author_rank: Regular Contributor
timestamp: November 06, 2024, 11:53:58 am
content: Quote from: BrianHG on November 06, 2024, 02:13:36 amYes, I tried to split the whole schematics into sub pages but, after researching, it seems it's not possible under Quartus.

author: BrianHG
author_rank: Super Contributor
timestamp: November 06, 2024, 06:36:37 pm
content: Quote from: caius on November 06, 2024, 11:53:58 amLOL, did you even try any of the tutorials?Did you even try to Youtube search Quartus schematic entry tutorials?

author: caius
author_rank: Regular Contributor
timestamp: November 06, 2024, 07:10:07 pm
content: Quote from: BrianHG on November 06, 2024, 06:36:37 pmI read some posts on Intel forums and found no answers.OK, I'm a dumbRegarding this project, I will put it aside , I'm not able to debug it (plus, I have no oscilloscope at the moment for doing comparison between original signals and FPGA ones).Thanks you, guys, for the help, anyway!

author: BrianHG
author_rank: Super Contributor
timestamp: November 06, 2024, 07:34:40 pm
content: Quote from: caius on November 06, 2024, 11:53:58 amLOL, did you even try any of the tutorials?Did you even try to Youtube search Quartus schematic entry tutorials?I've been using Quartus since the early 2000's and I have may multipage schematics.Did you not think to make a schematic with input, output and bidir pins?Then, 'generate a block symbol' for that schematic sheet?Then you could place any 1 or multiple of those generated block symbols on any other schematics...See my attached project, no problems here...

author: caius
author_rank: Regular Contributor
timestamp: November 06, 2024, 08:59:01 pm
content: Quote from: BrianHG on November 06, 2024, 07:34:40 pmYes, sorry, I have to study moreQuote from: BrianHG on November 06, 2024, 07:34:40 pmDo you mean a Quartus block schematics with input, output and bidir pins thren assigned to I/O of the FPGA?I put I/O on top of my messy block schematics if you mean thisQuote from: BrianHG on November 06, 2024, 07:34:40 pmMany thanks.I can see you did a single 512x8-bit RAM module instead of two 256x8-bit ones.Now I have to figure out how to interface it to my messy schematics (first of all I have to change label names, I think)Shame that the Verilog code (not made by me) is mostly working, just few glitches.But, as you guys said, perhaps it can't run on a FPGA.

author: BrianHG
author_rank: Super Contributor
timestamp: November 07, 2024, 01:00:33 am
content: Quote from: caius on November 06, 2024, 08:59:01 pmIt can run on a FPGA, you just need to be a little more smart about it.Take a look at my Quartus project I sent you. Notice the schematic with the onship memory. It shows you that there is a DFF latch for the input controls on that memory. This means in your schematic, the BARRY DEVIN and DONNY are already located inside the startic ram's block diagram, (I hope you double clicked on it to see the inside...) this means to match your schematic functions, you need to omit those 3 ICs and just feed their clock into the block-ram's clock.Most of everything else should just match away...Another thing, get rid of the way my tristate is wired. Remove LOIC and LEO, they are only a buffers feeding in the static ram's DATA-INPUT port. Just wire the bidir pins PIN_D[0..7] to the onchip memory DIN while the memory output is wired through a tristate to the bidir pins for output.Glitches means timing constraints errors. Did you create a .sdc constraints file?QuoteThe input, output and bidir pins only go to pin if they are on the top hierarchy schematic sheet. On all other sub-schematic sheets, those pins become input and output ports for the symbol you generate which you can place on any other higher level schematic sheet.

author: caius
author_rank: Regular Contributor
timestamp: November 07, 2024, 10:04:57 am
content: Quote from: BrianHG on November 07, 2024, 01:00:33 amIt would be greatQuote from: BrianHG on November 07, 2024, 01:00:33 amYes, I did see, many thanks.I guess the 'caius_top.bdf' is the top of hierarchy and this is what I have to insert in my schematics.What is unclear to me is which labels I have to change in this block to be adapted to my schematics.Quote from: BrianHG on November 07, 2024, 01:00:33 amYes, I can see.This means I have to remove all the BUF_D[7..0] labels in the whole schematics and use the PIN_D[7..0] instead (see the two 74283 JASON-GRACIE, the two 74157 JASON2-JOSHUA and the two 74373 KARSON/LUKE and JACK/JOHN)Quote from: BrianHG on November 07, 2024, 01:00:33 amNo, I have not created a .sdc constraints file, I always thought it was not really important.Anyway, the glitches are when I try the Verilog file, the block schematics are still untested on MAX10 FPGA until I get them succesfully compiled in Quartus.I posted the Verilog code above, almost perfect on MAX10, maybe we can work on it and improve it instead of doing Quartus block schematics?I don't know and ask you, expert guys, which is the best solution.Quote from: BrianHG on November 07, 2024, 01:00:33 amGot it.I usally use inputs, output and bidir pins to FPGA I/O on the whole schematics and then use wires with labels to the inputs and outputs ports of the symbols (more or less like I do in KiCad with global lables)P.S.I attach the Quartus project folder, it's better than an exported .jpg.

author: BrianHG
author_rank: Super Contributor
timestamp: November 07, 2024, 11:17:58 pm
content: If you problem is glitches, not full functionality, have you tried inverting the incoming clock?Does you incoming clock go through a 'GLOBAL' dedicated clock input and go through a 'GLOBAL CLK' buffer?Did you try put the input clock through a PLL set to 1:1 and adjust the output clock phase, or use multiple PLL output clock phases like 0deg, 90deg, 180deg, 270deg, and use those output for separate sections of your design?Remember, internally, the FPGA will do some thing much faster than TTL ICs. Using delayed clocks in the right places may help.Also, are you using the SignalTap/2 to realtime see what's happening inside your FPGA as it runs.

author: caius
author_rank: Regular Contributor
timestamp: November 07, 2024, 11:49:31 pm
content: Quote from: BrianHG on November 07, 2024, 11:17:58 pmYes, I tried to invert the clock with no successQuote from: BrianHG on November 07, 2024, 11:17:58 pmIt goes to pin 27 of the MAX10 FPGA (whch shod be a dedicated CLOCK input) directly and not through a 'GLOBAL CLK' buffer.Quote from: BrianHG on November 07, 2024, 11:17:58 pmI used a PLL (8MHz:8MHz) like you suggested me in the other thread , this improved things close to perfection , now left only some garbage objects (not really "glitches") on a specific game board (all the other run fine wit the FPGA replacement)Quote from: BrianHG on November 07, 2024, 11:17:58 pmYes, I know FPGA is much faster than TTL ICs, this is where the problem lies IMHO but I'm not able to pinpoint and debug it.That's why I decided (instead of using the Verilog code made by the author of schematis) to translate the TTL schematics into Quartus block schematics to see if, at least, that garbage goes away.But, until I'm not able to compile and synthetize the Quartus block schematics I can't try anything.Quote from: BrianHG on November 07, 2024, 11:17:58 pmNo, I'm not using it.Also, I have no scope at the moment, only a cheap logic analyzer.I may hook up this on outputs of the FPGA and compare them to the outputs of original custom IC.

author: BrianHG
author_rank: Super Contributor
timestamp: November 08, 2024, 12:01:18 am
content: Quote from: caius on November 07, 2024, 11:49:31 pmSignal tap gives you a digital logic analyzer of the FPGA IOs and internals.Instead of a scope, get a USB based 16 channel logic analyzer for your PC.EG: (now, I'm not condoning this brand, but if 8 channel 24mhz is enough for your 8mhz Z80, maybe or something a bit better)Dirt junk logic analyzerMuch more respectableDon't forget to try different clock phases for the IO buffers and the internal ram.Also try to clock the ram at 2X speed, 16Mhz. This will make it appear more like static ram.If the PLL helped lower the glitching, the finalizing the .sdc file, or even the basic simplest .sdc entry for the PLL alone may help clean up the remaining junk.Also, for slow IOs, you can set the input/output pin speeds to slow slew rate or play with the drive current for the output pins.

author: caius
author_rank: Regular Contributor
timestamp: November 08, 2024, 10:36:30 am
content: Quote from: BrianHG on November 08, 2024, 12:01:18 amI have this logic analyzer :https://hobbycomponents.com/our-brand-exclusives/1000-hobby-components-16-channel-logic-analyserQuote from: BrianHG on November 08, 2024, 12:01:18 amHow to try the clock phases on IO buffers and internal RAM or clock the RAMs at 16MHz?I'm now using the Verilog file and not Quartus schematics where I could see and wire the RAMs blocks.@BrianHG, I was not able to implement your 'caius' project you kindly earlier posted on this thread.Maybe you can look at it?I posted the whole Quartus schemarics prjoject earlier.Just to clear, I don't want ready-made food from you because I want to learn myself!(sadly, time for me is a big issue since I live alone and must do all by myself, my life is very hectic)Quote from: BrianHG on November 08, 2024, 12:01:18 amYes, I already set the PLL you kindly gave me in the other thread here and had big improvements :https://www.eevblog.com/forum/fpga/help-on-translate-schematics-to-verilog/msg5483155/#msg5483155I wanted to create an .SDC file but it seems Quartus Prime 17 (the version I'm using) has no wizard for the the TimeQuest Timing Analyzer (unlike version 13 which has it).May I create the .SDC file with TLC syntax?Anyway, there some values (tsu, th, etc..) I must figure outQuote from: BrianHG on November 08, 2024, 12:01:18 amAlready tried the SLOW SLEW RATE and different settings of drive current on the PIN Planner with no improvements or changes.

author: BrianHG
author_rank: Super Contributor
timestamp: November 08, 2024, 04:57:15 pm
content: Quote from: caius on November 08, 2024, 10:36:30 amStart a new blank project from scratch with a new name.Make a block diagram with an input and 2 output pins.Go into the megafunctions and look for clocking and select the normal PLL.Configure your PLL clock for 1 input at 8mhz and 2 outputs at 8mhz and 16mhz.Make sure the .bsf [ x ] is selected to be generated before you finish (block symbol file)Now, double click on a blank section of your schematic and select in the available dropdown directories your project directory. You will see your PLL there. Place it on the sheet.Tie the inputs and outputs.Start analysis and elab int the compile menu.Assign IO pins numbers to your ins and outs.Do a full compile.Verify that your PCB works.,Next, add your address and data IO pins.Go into the megafunctions section for onchip memory an create a 512x8 ram chip with the features you want.Make sure the .bsf [ x ] is selected to be generated before you finish (generate a block symbol file)Now, double click on a blank section of your schematic and select in the available dropdown directories your project directory. You will see your PLL and new memory there. Place it on the sheet.Tie the inputs and outputs.Compile.If working, delete the ram.Make a new schematicblock diagram called memory section.Inside that document, place the memory there.Remember, you can copy and paste objects from schematic sheet to another schematic sheet so long as all the custom components exist in you project library.AGAIN, go to youtube and watch some Quartus tutorials by Altera or any third party Youtuber. These things should be somewhere out there.

author: caius
author_rank: Regular Contributor
timestamp: November 08, 2024, 11:28:44 pm
content: Thanks BrianHG for putting your time on this.I will try ASAP but no success is guaranteed hereP.S.I see Quartus megafunction of RAM lacks of CHIP SELECT input, how to hande this since RAMs in my schematcs do have it ?

author: BrianHG
author_rank: Super Contributor
timestamp: November 08, 2024, 11:31:23 pm
content: Quote from: caius on November 08, 2024, 11:28:44 pmChip select should just go though a gate with the write enable to drive the write enable on the ram.Also, in the ram megafunction setup page, you will see an option to enable an 'read and write enable' input ports.Remember, those ports are positive logic.

author: caius
author_rank: Regular Contributor
timestamp: November 09, 2024, 11:44:51 pm
content: Quote from: BrianHG on November 08, 2024, 11:31:23 pmI followed your steps and miserably failed.I attach the "memory" project.When I implement it in my schematics and try a compile I get the same errors about some pins configting (those BUF_D[7..0]) with mutiple drivers (log attached).I attach also my Quartus schematics again if someone wants to take a look.Here's how the garbage graphics is displayed on screen when I try the FPGA replacement running the attached Verilog code.You can see the junk generated on power up and then stay on screen, this lead me think some wrong data is written on RAM (due to timing issue, perhaps?)https://youtu.be/KhEuuS7UCbIQuote from: BrianHG on November 08, 2024, 11:31:23 pmYes, I know they are active HIGH while in my schematics they are active LOW.I can I can use an inverter on each port of simulate RAM, I think