Reply by Brad Smallridge January 15, 20062006-01-15
OK, well, I think I have my addressing fixed, and the code below
is for a 9 bit ROM, which is what I originally wanted.  It seems to
generate acceptable output, at least for small numbers. I am using
the new ISE 8.i simulator. I will test it with larger values later.

Thanks Ray and Sylvain for taking the time to pick out my mistake.
I should have known.

A number of new questions arise:

1)  Is the code around the "begin" keyword, which maps the inputs
to the primitive RAMB16 (BRAM or Block RAM) acceptable or
is there a more concise/better method?

2)  I initially went to the V4 library guide and found this primitive.
I did not see there the RAMB_Sx_Sy primitives of Spartan yore,
which lead me to believe that they are abandoned in Virtex-4.
The Xilinx Virtex-4 User Guide ( ug070.pdf ) page 133 would
lead one to believe that they are available.  What is the story here?

3) Generally, I would like to transport my future designs between
Spartan3s and Virtex-4 effortlessly.  Are their any tips, ap notes,
or other information out there on how to do this?

4) The INIT_xx => sytax is clumsy.  Especially if I choose
to use the ninth bit.  What alternatives do I have?

5) I have been searching Google for code examples with the words
RAMB16 and std_logic.  Is there any primitive or keyword
specific to Virtex-4 that would further refine my search?

6) I did not see the INIT value on the ISE 8.1 simulation which
I expect to see at time 0.  Is this a glitch in the 8.1 simulator?

Regards,

Brad Smallridge
aivision dot com

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

library UNISIM;
use UNISIM.VComponents.all;

entity bram9p is
 port (
   clkb   :  IN std_logic;
   enb    :  IN std_logic;
   ssrb   :  IN std_logic;
   regceb :  IN std_logic;
   addrb  :  IN std_logic_VECTOR(11 downto 0);
   web    :  IN std_logic;
   doutb  : OUT std_logic_VECTOR( 8 downto 0) );
end bram9p;

architecture Behavioral of bram9p is

   signal addrb15 : std_logic_vector(14 downto 0);
   signal dob32   : std_logic_vector(31 downto 0);
   signal dopb4   : std_logic_vector( 3 downto 0);
   signal web4    : std_logic_vector( 3 downto 0);

begin

   addrb15(14 downto 3) <= addrb;
   addrb15( 2 downto 0) <= "000";
   doutb(7 downto 0)    <= dob32(7 downto 0);
   doutb(8)             <= dopb4(0);

   -- Update all web bits,
   -- otherwise only some addresses will be written.
   web4(0) <= web;
   web4(1) <= web;
   web4(2) <= web;
   web4(3) <= web;

   -- RAMB16: Virtex-4 16k+2k Parity Paramatizable BlockRAM
   -- Xilinx  HDL Language Template version 8.1i
   RAMB16_inst : RAMB16
   generic map (
      DOA_REG => 0, -- Optional output registers on the A port (0 or 1)
      DOB_REG => 0, -- Optional output registers on the B port (0 or 1)
      INIT_A => X"000000000", --  Initial values on A output port
      INIT_B => X"000000001", --  Initial values on B output port
      INVERT_CLK_DOA_REG => FALSE, -- TRUE or FALSE
      INVERT_CLK_DOB_REG => FALSE, -- TRUE or FALSE
      RAM_EXTENSION_A => "NONE", -- "UPPER", "LOWER" or "NONE" when cascaded
      RAM_EXTENSION_B => "NONE", -- "UPPER", "LOWER" or "NONE" when cascaded
      READ_WIDTH_A =>  9, -- Valid values are 1,2,4,9,18 or 36
      READ_WIDTH_B =>  9, -- Valid values are 1,2,4,9,18 or 36
      SIM_COLLISION_CHECK => "NONE", --  
"ALL","WARNING_ONLY","GENERATE_X_ONLY,"NONE
      SRVAL_A => X"000000000", --  Port A ouput value upon SSR assertion
      SRVAL_B => X"000000002", --  Port B ouput value upon SSR assertion
      WRITE_MODE_A => "READ_FIRST", --  WRITE_FIRST, READ_FIRST or NO_CHANGE
      WRITE_MODE_B => "READ_FIRST", --  WRITE_FIRST, READ_FIRST or NO_CHANGE
      WRITE_WIDTH_A =>  9, -- 1,2,4,9,18 or 36
      WRITE_WIDTH_B =>  9, -- 1,2,4,9,18 or 36
      -- The following INIT_xx declarations specify the initial contents of 
the RAM
      INIT_00 => 
X"1F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100",
      INIT_01 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_02 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_03 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_04 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_05 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_06 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_07 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_08 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_09 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_0A => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_0B => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_0C => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_0D => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_0E => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_0F => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_10 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_11 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_12 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_13 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_14 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_15 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_16 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_17 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_18 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_19 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_1A => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_1B => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_1C => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_1D => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_1E => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_1F => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_20 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_21 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_22 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_23 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_24 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_25 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_26 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_27 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_28 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_29 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_2A => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_2B => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_2C => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_2D => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_2E => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_2F => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_30 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_31 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_32 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_33 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_34 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_35 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_36 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_37 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_38 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_39 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_3A => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_3B => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_3C => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_3D => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_3E => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_3F => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      -- The next set of INITP_xx are for the parity bits
      INITP_00 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INITP_01 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INITP_02 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INITP_03 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INITP_04 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INITP_05 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INITP_06 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INITP_07 => 
X"0000000000000000000000000000000000000000000000000000000000000000")
   port map (
      CASCADEOUTA => open,                  -- 1-bit cascade output
      CASCADEOUTB => open,                  -- 1-bit cascade output
      DOA         => open,                  -- 32-bit A port Data Output
      DOB         => dob32,                 -- 32-bit B port Data Output
      DOPA        => open,                  -- 4-bit  A port Parity Output
      DOPB        => dopb4,                 -- 4-bit  B port Parity Output
      ADDRA       => (others=>'0'),         -- 15-bit A port Address Input
      ADDRB       => addrb15,               -- 15-bit B port Address Input
      CASCADEINA  => '0',                   -- 1-bit cascade A input
      CASCADEINB  => '0',                   -- 1-bit cascade B input
      CLKA        => '0',                   -- Port A Clock
      CLKB        => clkb,                  -- Port B Clock
      DIA         => (others=>'0'),         -- 32-bit A port Data Input
      DIB         => (others=>'0'),         -- 32-bit B port Data Input
      DIPA        => (others=>'0'),         -- 4-bit  A port parity Input
      DIPB        => (others=>'0'),         -- 4-bit  B port parity Input
      ENA         => '0',                   -- 1-bit  A port Enable Input
      ENB         => enb,                   -- 1-bit  B port Enable Input
      REGCEA      => '0',                   -- 1-bit A port register enable 
input
      REGCEB      => regceb,                -- 1-bit B port register enable 
input
      SSRA        => '0',                   -- 1-bit  A port Synchronous 
Set/Reset Input
      SSRB        => ssrb,                  -- 1-bit  B port Synchronous 
Set/Reset Input
      WEA         => "0000",                -- 4-bit  A port Write Enable 
Input
      WEB         => web4 );                -- 4-bit  B port Write Enable 
Input

end Behavioral;



Reply by Jim Granville January 15, 20062006-01-15
Hal Murray wrote:

>>There is a natural vested interest in NOT listing too many bugs in SW. > > > Not where I come from. > > Doug Clark wrote a great paper - "Bugs are Good". Unfortunately, I > don't think it's available online. > > Context is roughly: > > Don't shoot the messenger. Praise the people who find the problems > before you tape out. > > Discuss the bugs you find. Why weren't they found sooner? > Where are there similar structures that should be examined/probed? > > If you can accurately keep track of bugs, then you can plot bugs > discovered over time. When that falls off it's time to ship. > > > I think it's a culture thing. It's much better to find bugs sooner. > The trick is to make sure that everybody understands that - management > too. You need somethingthings like a senior designer standing up in public > and saying thanks to a new hire.
100% Agree - for a properly-run engineering company. However, as companies get more dominated by market-droids, and someone suggests this info is made more public/user accessible, that's where you will see the push-back : Write your own Dilbert lines here : " Hang on, All these defect reports makes our SW look bad - quality was better before" " Those defects will only affect very few customers, so why tell everyone about them ? " Xilinx press releases show some of this mindset already : My present most entertaining favourite is the ISE 8.1i release that says :: "WebPACK 8.1i&#4294967295;s ISE Fmax Technology ... up to 70 percent faster performance than competing FPGA products" [Is this a laundry product, or Engineering SW they are selling ? ] Sounds great, warm fuzzies all round, until you look for meaning.... - Note, no comparison with EARLIER ISE releases, only with someone else's (un-named) offering, and then it's the meanginless "up to" caveat. There is another end to this scale as well, which is "down to" - why is that never published in these press releases ? :) -jg
Reply by Hal Murray January 15, 20062006-01-15
>There is a natural vested interest in NOT listing too many bugs in SW.
Not where I come from. Doug Clark wrote a great paper - "Bugs are Good". Unfortunately, I don't think it's available online. Context is roughly: Don't shoot the messenger. Praise the people who find the problems before you tape out. Discuss the bugs you find. Why weren't they found sooner? Where are there similar structures that should be examined/probed? If you can accurately keep track of bugs, then you can plot bugs discovered over time. When that falls off it's time to ship. I think it's a culture thing. It's much better to find bugs sooner. The trick is to make sure that everybody understands that - management too. You need somethingthings like a senior designer standing up in public and saying thanks to a new hire. -- The suespammers.org mail server is located in California. So are all my other mailboxes. Please do not send unsolicited bulk e-mail or unsolicited commercial e-mail to my suespammers.org address or any of my other addresses. These are my opinions, not necessarily my employer's. I hate spam.
Reply by Jim Granville January 15, 20062006-01-15
Ray Andraka wrote:
[User feedback that should have almost everyone in Xilinx cringing..]
<snip>
> OK, so for a better way. #1 Listen to the users of your software, and I > mean all of them, not just your biggest 5 accounts. #2, stop the > software folks from mucking with the software. Fix what is broken > before adding new features, and for Gosh sakes stop the gratuitous > changes that seem to break everything. #3, work on the support for the > software you have. #4, organize the answers data base, perhaps with a > pre-filter that asks you which device, version of ISE, and maybe > synthesis tool you are using so I don't get 1001 answers for ISE4.1 when > I am trying to use 7.1. #5, don't just cut off support for an older > version (eg 6.3sp3, which works better than 7.1 except the timing > parameters haven't been updated)
Very good point : Xilinx: So HOW hard is it, to update the timing parameters ? Actually, SURELY Xilinx do that internally, otherwise HOW do they know they ARE moving forwards in SW, and not simply being carried by the silicon ??! if the newer version is still loaded
> with fatal bugs. When I report a problem with 6.3, the only answer that > is returned is use 7.1 (never mind the fact that 7.1 did not work at all > until sp4 for any design I ran it on) #6. Fix the bugs in a major > release before committing all your effort to the next major release. #7 > Listen to your users, some of them do know what they are talking about.
How about #8 : Get the SW writers to actually USE the tools ?! Some of the failings reported here, are frankly, stunningly stupid. eg Inverted outputs on CPLDs - I'd really LOVE to hear just how that flew thru all the supposed regression testing ?. --Let me guess - they only tested SW, and no one thought to try real silicon ?!
> Things like the FIFO16 restrictions need to be in the user manual so > that the designer is aware of them before he design them in so that he > can work around the limitations. Easy to work around if given the > information. A real pain the tail to find the problem if you are not > aware of the limitations, and none too fun to rework the design to work > within the limitations when you do learn about them. For known bugs in > the software, there really should be an errata sheet listing the known > issues that can trip up a design (like the pipeline register remapping > or what ever you call it) so that when you run into a problem like this > you have a prayer of finding an answer record on it. Maybe all it takes > is a refinement of the search engine. I don't know, that isn't my area > of expertise. I think the fact that you also didn't post any relevant > answer records to Brads post that started this should be a flag to you > showing you that the system isn't working too.
This is something of a catch 22: To fully document problems, Xilinx must first understand them. However, if they understood them, they would be fixed/eliminated very quickly. There is a natural vested interest in NOT listing too many bugs in SW. It is classic large company spin, to appear to give support and information, when actually doing neither.
> > Another suggestion is better testing of your software before you release > it, not just on the mainstream push the big green button to make a 40 > Mhz design designs either, but some with some handcrafting that are > pushing the clock capabilities of the devices.
I'm sure Ray could give Xilinx some very good 'real world' test cases ? While the compile
> completion times have gotten remarkably good, the quality of results for > a pretty well optimized design (one that includes tight floorplanning) > have fallen off with each major release since 4.1. I know other users > have remarked as such here, so I know I am not the only one. The > regression testing really does need to include the full spectrum of > designs, unless Xilinx really is trying to kill off the RLOC as was > speculated here many years ago. > > OK, sorry about the rant (well, not really). This thread just happened > to pour vinegar into an open wound, and well, your answer did nothing to > soothe the pain.
-jg
Reply by Ray Andraka January 14, 20062006-01-14
Brad, it is your addressing.  For the wider data widths, the lsbs of the 
address should be held at zero.  You should use bits 14 downto whatever 
is appropriate for the aspect ratio you are using (in your case the 36 
bit should leave the 5 lsbs '0').



Brad Smallridge wrote:

> Thanks for words of encouragement Ray. > > I went back to double check if all the simulation > and libraries were downloaded and installed. It > seems as if they are. All from the download page > that Xilinx is advertising on the home page right > now for the 8.i software. Three packages in all, > the ISE, ModelSim III, and it's library. > > I am still not getting any output from the RAMB16 > p
Reply by Ray Andraka January 14, 20062006-01-14
Austin Lesea wrote:
> Ray, > > I know, I know! > > We are really open to any good ideas.
Austin, For starters, it would help if your hotline folks were up on the current cases. For example, I recently ran across an issue in 7.1sp4 where pipeline stages are getting added to my DSP48's by teh implementation tools, and causing the hardware to behave differently than functional sim (first off, that should be left to synthesis, not PAR). I opened a case for it (case 614397 if you are interested) a bit over a week ago. The only responses I got (and I had to go to the website to find the first after getting the second offering to close the case) was a superbly helpful statement that he wasn't aware of any differences in the behavior between 6.3 (which works fine) and 7.1, and were there any differences between the timing simulations for the two. I found out asking around inside Xilinx that the 7.1sp4 mapper tries to be cute by moving registers in and out of DSP48's, but ignores any effects it might have on timing in parallel pipeline paths. Now, I searched high and low through the answers database for anything with pipeline register and DSP in it, but couldn't find a relevant answer anywhere. My source inside xilinx asked around and found out about answer 22314, which tells how to disable this odd behavior with an environment variable (turns out the word pipeline wasn't in the keywords, so your search engine didn't turn up this answer record). Once again a "known" behavior that took close to a week of my time tracking down, and even the hotline help couldn't find a relevant answer. Perhaps you see this as acceptable (I sure wish I could bill someone for all the debug time I have expended this past 6 months chasing down problems in the silicon or tools and finding suitable work-arounds), but I certainly don't. The current system is broken when the designer has to resort to inside contacts in order to track down problems in his design caused by undocumented but known behavior of the silicon or the tools. I can't imagine that I am the only one running into these issues with Virtex4 (this one, placement of DSP48s with pre-SP4 7.1 tools, problems with the Xilinx DCM NBTI fix circuit, and FIFO16 problems to name a few of the big ones that tripped me up). It wouldn't inflame me if it didn't come down to me spending tens or hundreds of hours on each, and then hearing "oh, yeah, we knew about that". I have spent well over 1/3rd of my time in the past 6 months chasing or correcting issues caused by tools or silicon. That is time that is generally not paid by my customers, plus it makes a significant dent in my schedule. OK, so for a better way. #1 Listen to the users of your software, and I mean all of them, not just your biggest 5 accounts. #2, stop the software folks from mucking with the software. Fix what is broken before adding new features, and for Gosh sakes stop the gratuitous changes that seem to break everything. #3, work on the support for the software you have. #4, organize the answers data base, perhaps with a pre-filter that asks you which device, version of ISE, and maybe synthesis tool you are using so I don't get 1001 answers for ISE4.1 when I am trying to use 7.1. #5, don't just cut off support for an older version (eg 6.3sp3, which works better than 7.1 except the timing parameters haven't been updated) if the newer version is still loaded with fatal bugs. When I report a problem with 6.3, the only answer that is returned is use 7.1 (never mind the fact that 7.1 did not work at all until sp4 for any design I ran it on) #6. Fix the bugs in a major release before committing all your effort to the next major release. #7 Listen to your users, some of them do know what they are talking about. Things like the FIFO16 restrictions need to be in the user manual so that the designer is aware of them before he design them in so that he can work around the limitations. Easy to work around if given the information. A real pain the tail to find the problem if you are not aware of the limitations, and none too fun to rework the design to work within the limitations when you do learn about them. For known bugs in the software, there really should be an errata sheet listing the known issues that can trip up a design (like the pipeline register remapping or what ever you call it) so that when you run into a problem like this you have a prayer of finding an answer record on it. Maybe all it takes is a refinement of the search engine. I don't know, that isn't my area of expertise. I think the fact that you also didn't post any relevant answer records to Brads post that started this should be a flag to you showing you that the system isn't working too. Another suggestion is better testing of your software before you release it, not just on the mainstream push the big green button to make a 40 Mhz design designs either, but some with some handcrafting that are pushing the clock capabilities of the devices. While the compile completion times have gotten remarkably good, the quality of results for a pretty well optimized design (one that includes tight floorplanning) have fallen off with each major release since 4.1. I know other users have remarked as such here, so I know I am not the only one. The regression testing really does need to include the full spectrum of designs, unless Xilinx really is trying to kill off the RLOC as was speculated here many years ago. OK, sorry about the rant (well, not really). This thread just happened to pour vinegar into an open wound, and well, your answer did nothing to soothe the pain.
Reply by Brad Smallridge January 14, 20062006-01-14
Aha! Thank you.

> Your BRAM is configured as 36bits width. So the > 5 LSBs bit address should be zeroes all the time.
Reply by Sylvain Munaut January 14, 20062006-01-14
Your BRAM is configured as 36bits width. So the
5 LSBs bit address should be zeroes all the time.

Cfr ug070.pdf page 120.


Sylvain


Brad Smallridge wrote:
> Thanks for words of encouragement Ray. > > I went back to double check if all the simulation > and libraries were downloaded and installed. It > seems as if they are. All from the download page > that Xilinx is advertising on the home page right > now for the 8.i software. Three packages in all, > the ISE, ModelSim III, and it's library. > > I am still not getting any output from the RAMB16 > primitive. Seems to get stuck on the 0th address. > I have wiggled all the signals but I all I can see is > is the init value and the 0th address value. Please > take a look at my wrapper file and I also included > the VHDL generated from the Waveform tool after > the Generate Expected Value option. I know it is > probably some silly mistake. > > Brad Smallridge aivision > > library IEEE; > use IEEE.STD_LOGIC_1164.ALL; > use IEEE.STD_LOGIC_ARITH.ALL; > use IEEE.STD_LOGIC_UNSIGNED.ALL; > > library UNISIM; > use UNISIM.VComponents.all; > > entity bram9p is > port ( > clkb : IN std_logic; > enb : IN std_logic; > ssrb : IN std_logic; > regceb : IN std_logic; > addrb : IN std_logic_VECTOR(14 downto 0); > web : IN std_logic_VECTOR( 3 downto 0); > doutb : OUT std_logic_VECTOR(31 downto 0) ); > end bram9p; > > architecture Behavioral of bram9p is > > begin > > -- RAMB16: Virtex-4 16k+2k Parity Paramatizable BlockRAM > -- Xilinx HDL Language Template version 8.1i > RAMB16_inst : RAMB16 > generic map ( > DOA_REG => 0, -- Optional output registers on the A port (0 or 1) > DOB_REG => 0, -- Optional output registers on the B port (0 or 1) > INIT_A => X"000000000", -- Initial values on A output port > INIT_B => X"000000003", -- Initial values on B output port > INVERT_CLK_DOA_REG => FALSE, -- Invert clock on A port output > registers (TRUE or FALSE) > INVERT_CLK_DOB_REG => FALSE, -- Invert clock on B port output > registers (TRUE or FALSE) > RAM_EXTENSION_A => "NONE", -- "UPPER", "LOWER" or "NONE" when cascaded > RAM_EXTENSION_B => "NONE", -- "UPPER", "LOWER" or "NONE" when cascaded > READ_WIDTH_A => 36, -- Valid values are 1,2,4,9,18 or 36 > READ_WIDTH_B => 36, -- Valid values are 1,2,4,9,18 or 36 > SIM_COLLISION_CHECK => "NONE", -- Collision check enable "ALL", > "WARNING_ONLY", "GENERATE_X_ONLY > -- or "NONE > SRVAL_A => X"000000000", -- Port A ouput value upon SSR assertion > SRVAL_B => X"CCCCCCABC", -- Port B ouput value upon SSR assertion > WRITE_MODE_A => "READ_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE > WRITE_MODE_B => "READ_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE > WRITE_WIDTH_A => 36, -- Valid values are 1,2,4,9,18 or 36 > WRITE_WIDTH_B => 36, -- Valid values are 1,2,4,9,18 or 36 > -- The following INIT_xx declarations specify the initial contents of > the RAM > INIT_00 => > X"00D00A0100010B01000100010001000100010001000100010001DEAD00100112", > INIT_01 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_02 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_03 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_04 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_05 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_06 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_07 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_08 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_09 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_0A => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_0B => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_0C => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_0D => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_0E => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_0F => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_10 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_11 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_12 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_13 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_14 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_15 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_16 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_17 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_18 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_19 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_1A => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_1B => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_1C => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_1D => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_1E => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_1F => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_20 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_21 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_22 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_23 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_24 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_25 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_26 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_27 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_28 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_29 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_2A => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_2B => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_2C => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_2D => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_2E => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_2F => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_30 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_31 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_32 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_33 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_34 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_35 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_36 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_37 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_38 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_39 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_3A => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_3B => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_3C => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_3D => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_3E => > X"0000000000000000000000000000000000000000000000000000000000000000", > INIT_3F => > X"00D00A0100010B01000100010001000100010001000100010001DEAD00100112", > -- The next set of INITP_xx are for the parity bits > INITP_00 => > X"00D00A0100010B01000100010001000100010001000100010001DEAD00100112", > INITP_01 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INITP_02 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INITP_03 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INITP_04 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INITP_05 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INITP_06 => > X"0000000000000000000000000000000000000000000000000000000000000000", > INITP_07 => > X"00D00A0100010B01000100010001000100010001000100010001DEAD00100112") > port map ( > CASCADEOUTA => open, -- 1-bit cascade output > CASCADEOUTB => open, -- 1-bit cascade output > DOA => open, -- 32-bit A port Data Output > DOB => doutb(31 downto 0), -- 32-bit B port Data Output > DOPA => open, -- 4-bit A port Parity Output > DOPB => open, -- 4-bit B port Parity Output > ADDRA => (others=>'0'), -- 15-bit A port Address Input > ADDRB => addrb(14 downto 0), -- 15-bit B port Address Input > CASCADEINA => '0', -- 1-bit cascade A input > CASCADEINB => '0', -- 1-bit cascade B input > CLKA => '0', -- Port A Clock > CLKB => clkb, -- Port B Clock > DIA => (others=>'0'), -- 32-bit A port Data Input > DIB => (others=>'0'), -- 32-bit B port Data Input > DIPA => (others=>'0'), -- 4-bit A port parity Input > DIPB => (others=>'0'), -- 4-bit B port parity Input > ENA => '0', -- 1-bit A port Enable Input > ENB => enb, -- 1-bit B port Enable Input > REGCEA => '0', -- 1-bit A port register enable > input > REGCEB => regceb, -- 1-bit B port register enable > input > SSRA => '0', -- 1-bit A port Synchronous > Set/Reset Input > SSRB => ssrb, -- 1-bit B port Synchronous > Set/Reset Input > WEA => "0000", -- 4-bit A port Write Enable > Input > WEB => web ); -- 4-bit B port Write Enable > Input > > end Behavioral; > > > library IEEE; > use IEEE.STD_LOGIC_1164.ALL; > use IEEE.STD_LOGIC_ARITH.ALL; > use IEEE.STD_LOGIC_UNSIGNED.ALL; > library UNISIM; > use UNISIM.VComponents.all; > USE IEEE.STD_LOGIC_TEXTIO.ALL; > USE STD.TEXTIO.ALL; > > ENTITY waveform IS > END waveform; > > ARCHITECTURE testbench_arch OF waveform IS > FILE RESULTS: TEXT OPEN WRITE_MODE IS "results.txt"; > > COMPONENT bram9p > PORT ( > clkb : In std_logic; > enb : In std_logic; > ssrb : In std_logic; > regceb : In std_logic; > addrb : In std_logic_vector (14 DownTo 0); > web : In std_logic_vector (3 DownTo 0); > doutb : Out std_logic_vector (31 DownTo 0) > ); > END COMPONENT; > > SIGNAL clkb : std_logic := '0'; > SIGNAL enb : std_logic := '0'; > SIGNAL ssrb : std_logic := '0'; > SIGNAL regceb : std_logic := '0'; > SIGNAL addrb : std_logic_vector (14 DownTo 0) := "000000000000000"; > SIGNAL web : std_logic_vector (3 DownTo 0) := "0000"; > SIGNAL doutb : std_logic_vector (31 DownTo 0) := > "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU"; > > SHARED VARIABLE TX_ERROR : INTEGER := 0; > SHARED VARIABLE TX_OUT : LINE; > > constant PERIOD : time := 200 ns; > constant DUTY_CYCLE : real := 0.5; > constant OFFSET : time := 0 ns; > > BEGIN > UUT : bram9p > PORT MAP ( > clkb => clkb, > enb => enb, > ssrb => ssrb, > regceb => regceb, > addrb => addrb, > web => web, > doutb => doutb > ); > > PROCESS -- clock process for clkb > BEGIN > WAIT for OFFSET; > CLOCK_LOOP : LOOP > clkb <= '0'; > WAIT FOR (PERIOD - (PERIOD * DUTY_CYCLE)); > clkb <= '1'; > WAIT FOR (PERIOD * DUTY_CYCLE); > END LOOP CLOCK_LOOP; > END PROCESS; > > PROCESS > PROCEDURE CHECK_doutb( > next_doutb : std_logic_vector (31 DownTo 0); > TX_TIME : INTEGER > ) IS > VARIABLE TX_STR : String(1 to 4096); > VARIABLE TX_LOC : LINE; > BEGIN > IF (doutb /= next_doutb) THEN > STD.TEXTIO.write(TX_LOC, string'("Error at time=")); > STD.TEXTIO.write(TX_LOC, TX_TIME); > STD.TEXTIO.write(TX_LOC, string'("ns doutb=")); > IEEE.STD_LOGIC_TEXTIO.write(TX_LOC, doutb); > STD.TEXTIO.write(TX_LOC, string'(", Expected = ")); > IEEE.STD_LOGIC_TEXTIO.write(TX_LOC, next_doutb); > STD.TEXTIO.write(TX_LOC, string'(" ")); > TX_STR(TX_LOC.all'range) := TX_LOC.all; > STD.TEXTIO.writeline(RESULTS, TX_LOC); > STD.TEXTIO.Deallocate(TX_LOC); > ASSERT (FALSE) REPORT TX_STR SEVERITY ERROR; > TX_ERROR := TX_ERROR + 1; > END IF; > END; > BEGIN > -- ------------- Current Time: 85ns > WAIT FOR 85 ns; > ssrb <= '1'; > addrb <= "000000000000001"; > -- ------------------------------------- > -- ------------- Current Time: 115ns > WAIT FOR 30 ns; > CHECK_doutb("00000000000000000000000000000011", 115); > -- ------------------------------------- > -- ------------- Current Time: 285ns > WAIT FOR 170 ns; > ssrb <= '0'; > addrb <= "000000000000010"; > -- ------------------------------------- > -- ------------- Current Time: 485ns > WAIT FOR 200 ns; > enb <= '1'; > addrb <= "000000000000011"; > -- ------------------------------------- > -- ------------- Current Time: 515ns > WAIT FOR 30 ns; > CHECK_doutb("00000000000100000000000100010010", 515); > -- ------------------------------------- > -- ------------- Current Time: 685ns > WAIT FOR 170 ns; > regceb <= '1'; > addrb <= "000000000000100"; > -- ------------------------------------- > -- ------------- Current Time: 885ns > WAIT FOR 200 ns; > addrb <= "000000000000101"; > -- ------------------------------------- > -- ------------- Current Time: 1085ns > WAIT FOR 200 ns; > regceb <= '0'; > addrb <= "000000000000110"; > -- ------------------------------------- > -- ------------- Current Time: 1285ns > WAIT FOR 200 ns; > enb <= '0'; > addrb <= "000000000000111"; > -- ------------------------------------- > -- ------------- Current Time: 1485ns > WAIT FOR 200 ns; > regceb <= '1'; > addrb <= "000000000001000"; > -- ------------------------------------- > -- ------------- Current Time: 1685ns > WAIT FOR 200 ns; > regceb <= '0'; > addrb <= "000000000001001"; > -- ------------------------------------- > -- ------------- Current Time: 1885ns > WAIT FOR 200 ns; > addrb <= "000000000001010"; > web <= "1111"; > -- ------------------------------------- > -- ------------- Current Time: 2085ns > WAIT FOR 200 ns; > enb <= '1'; > addrb <= "000000000001011"; > -- ------------------------------------- > -- ------------- Current Time: 2285ns > WAIT FOR 200 ns; > enb <= '0'; > regceb <= '1'; > addrb <= "000000000001100"; > -- ------------------------------------- > -- ------------- Current Time: 2485ns > WAIT FOR 200 ns; > regceb <= '0'; > addrb <= "000000000001101"; > -- ------------------------------------- > -- ------------- Current Time: 2685ns > WAIT FOR 200 ns; > addrb <= "000000000001110"; > web <= "0000"; > -- ------------------------------------- > -- ------------- Current Time: 2885ns > WAIT FOR 200 ns; > addrb <= "000000000001111"; > -- ------------------------------------- > -- ------------- Current Time: 3085ns > WAIT FOR 200 ns; > addrb <= "000000000010000"; > -- ------------------------------------- > -- ------------- Current Time: 3285ns > WAIT FOR 200 ns; > ssrb <= '1'; > addrb <= "000000000010001"; > -- ------------------------------------- > -- ------------- Current Time: 3485ns > WAIT FOR 200 ns; > ssrb <= '0'; > addrb <= "000000000010010"; > -- ------------------------------------- > -- ------------- Current Time: 3685ns > WAIT FOR 200 ns; > addrb <= "000000000010011"; > -- ------------------------------------- > -- ------------- Current Time: 3885ns > WAIT FOR 200 ns; > addrb <= "000000000010100"; > -- ------------------------------------- > -- ------------- Current Time: 4085ns > WAIT FOR 200 ns; > addrb <= "000000000010101"; > -- ------------------------------------- > -- ------------- Current Time: 4285ns > WAIT FOR 200 ns; > addrb <= "000000000010110"; > -- ------------------------------------- > -- ------------- Current Time: 4485ns > WAIT FOR 200 ns; > addrb <= "000000000010111"; > -- ------------------------------------- > -- ------------- Current Time: 4685ns > WAIT FOR 200 ns; > addrb <= "000000000011000"; > -- ------------------------------------- > -- ------------- Current Time: 4885ns > WAIT FOR 200 ns; > addrb <= "000000000011001"; > -- ------------------------------------- > WAIT FOR 315 ns; > > IF (TX_ERROR = 0) THEN > STD.TEXTIO.write(TX_OUT, string'("No errors or > warnings")); > STD.TEXTIO.writeline(RESULTS, TX_OUT); > ASSERT (FALSE) REPORT > "Simulation successful (not a failure). No problems > detected." > SEVERITY FAILURE; > ELSE > STD.TEXTIO.write(TX_OUT, TX_ERROR); > STD.TEXTIO.write(TX_OUT, > string'(" errors found in simulation")); > STD.TEXTIO.writeline(RESULTS, TX_OUT); > ASSERT (FALSE) REPORT "Errors found during simulation" > SEVERITY FAILURE; > END IF; > END PROCESS; > > END testbench_arch; > > > > >
Reply by Brad Smallridge January 13, 20062006-01-13
Austin Lesea wrote:

> Ray, > I know, I know! > We are really open to any good ideas.
It's not that complicated. First, Xilinx needs more examples. Every release of a board, silicon, or software version should have an example tutorial of every basic component that a beginner would use. Right now Xilinx has a tutorial on how to simulate a counter. Whoop-De-Doo. There should be a tuorial on every simple component, fifos, serial ports, brams, iserdes, etc. Probably about 50 basic componets would suffice. Now that's a lot of writing, but it's probably more expensive having your case support people supporting everybody individually. And the software would be tested when it left the factory. Second, the support should be open. This case stuff doesn't help. Xilinx wants to route all these cases to an engineer that can answer the question, good luck. I have submitted three cases in the past two weeks and not gotten anything constructive. I have just discovered your forums but I see there isn't too much traffic there. I use to get answers from Xilinx engineers here on comp.arch.fpga. Have they been gaged? In terms of the old answers, and multitude of the information, I would only hope that Google can sort it all out. Seems like any Answer that says the problem is resolved with release so-and-so should be fine. Brad Smallridge aivision
Reply by Brad Smallridge January 13, 20062006-01-13
Thanks for words of encouragement Ray.

I went back to double check if all the simulation
and libraries were downloaded and installed. It
seems as if they are.  All from the download page
that Xilinx is advertising on the home page right
now for the 8.i software. Three packages in all,
the ISE, ModelSim III, and it's library.

I am still not getting any output from the RAMB16
primitive.  Seems to get stuck on the 0th address.
I have wiggled all the signals but I all I can see is
is the init value and the 0th address value.  Please
take a look at my wrapper file and I also included
the VHDL generated from the Waveform tool after
the Generate Expected Value option. I know it is
probably some silly mistake.

Brad Smallridge aivision

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

library UNISIM;
use UNISIM.VComponents.all;

entity bram9p is
 port (
   clkb   :  IN std_logic;
   enb    :  IN std_logic;
   ssrb   :  IN std_logic;
   regceb :  IN std_logic;
   addrb  :  IN std_logic_VECTOR(14 downto 0);
   web    :  IN std_logic_VECTOR( 3 downto 0);
   doutb  : OUT std_logic_VECTOR(31 downto 0) );
end bram9p;

architecture Behavioral of bram9p is

begin

   -- RAMB16: Virtex-4 16k+2k Parity Paramatizable BlockRAM
   -- Xilinx  HDL Language Template version 8.1i
   RAMB16_inst : RAMB16
   generic map (
      DOA_REG => 0, -- Optional output registers on the A port (0 or 1)
      DOB_REG => 0, -- Optional output registers on the B port (0 or 1)
      INIT_A => X"000000000", --  Initial values on A output port
      INIT_B => X"000000003", --  Initial values on B output port
      INVERT_CLK_DOA_REG => FALSE, -- Invert clock on A port output 
registers (TRUE or FALSE)
      INVERT_CLK_DOB_REG => FALSE, -- Invert clock on B port output 
registers (TRUE or FALSE)
      RAM_EXTENSION_A => "NONE", -- "UPPER", "LOWER" or "NONE" when cascaded
      RAM_EXTENSION_B => "NONE", -- "UPPER", "LOWER" or "NONE" when cascaded
      READ_WIDTH_A => 36, -- Valid values are 1,2,4,9,18 or 36
      READ_WIDTH_B => 36, -- Valid values are 1,2,4,9,18 or 36
      SIM_COLLISION_CHECK => "NONE", -- Collision check enable "ALL", 
"WARNING_ONLY", "GENERATE_X_ONLY
                                   -- or "NONE
      SRVAL_A => X"000000000", --  Port A ouput value upon SSR assertion
      SRVAL_B => X"CCCCCCABC", --  Port B ouput value upon SSR assertion
      WRITE_MODE_A => "READ_FIRST", --  WRITE_FIRST, READ_FIRST or NO_CHANGE
      WRITE_MODE_B => "READ_FIRST", --  WRITE_FIRST, READ_FIRST or NO_CHANGE
      WRITE_WIDTH_A => 36, -- Valid values are 1,2,4,9,18 or 36
      WRITE_WIDTH_B => 36, -- Valid values are 1,2,4,9,18 or 36
      -- The following INIT_xx declarations specify the initial contents of 
the RAM
      INIT_00 => 
X"00D00A0100010B01000100010001000100010001000100010001DEAD00100112",
      INIT_01 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_02 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_03 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_04 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_05 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_06 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_07 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_08 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_09 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_0A => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_0B => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_0C => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_0D => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_0E => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_0F => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_10 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_11 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_12 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_13 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_14 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_15 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_16 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_17 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_18 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_19 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_1A => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_1B => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_1C => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_1D => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_1E => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_1F => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_20 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_21 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_22 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_23 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_24 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_25 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_26 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_27 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_28 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_29 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_2A => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_2B => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_2C => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_2D => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_2E => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_2F => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_30 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_31 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_32 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_33 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_34 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_35 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_36 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_37 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_38 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_39 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_3A => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_3B => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_3C => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_3D => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_3E => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INIT_3F => 
X"00D00A0100010B01000100010001000100010001000100010001DEAD00100112",
      -- The next set of INITP_xx are for the parity bits
      INITP_00 => 
X"00D00A0100010B01000100010001000100010001000100010001DEAD00100112",
      INITP_01 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INITP_02 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INITP_03 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INITP_04 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INITP_05 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INITP_06 => 
X"0000000000000000000000000000000000000000000000000000000000000000",
      INITP_07 => 
X"00D00A0100010B01000100010001000100010001000100010001DEAD00100112")
   port map (
      CASCADEOUTA => open,                  -- 1-bit cascade output
      CASCADEOUTB => open,                  -- 1-bit cascade output
      DOA         => open,                  -- 32-bit A port Data Output
      DOB         => doutb(31 downto 0),    -- 32-bit B port Data Output
      DOPA        => open,                  -- 4-bit  A port Parity Output
      DOPB        => open,                  -- 4-bit  B port Parity Output
      ADDRA       => (others=>'0'),         -- 15-bit A port Address Input
      ADDRB       => addrb(14 downto 0),    -- 15-bit B port Address Input
      CASCADEINA  => '0',                   -- 1-bit cascade A input
      CASCADEINB  => '0',                   -- 1-bit cascade B input
      CLKA        => '0',                   -- Port A Clock
      CLKB        => clkb,                  -- Port B Clock
      DIA         => (others=>'0'),         -- 32-bit A port Data Input
      DIB         => (others=>'0'),         -- 32-bit B port Data Input
      DIPA        => (others=>'0'),         -- 4-bit  A port parity Input
      DIPB        => (others=>'0'),         -- 4-bit  B port parity Input
      ENA         => '0',                   -- 1-bit  A port Enable Input
      ENB         => enb,                   -- 1-bit  B port Enable Input
      REGCEA      => '0',                   -- 1-bit A port register enable 
input
      REGCEB      => regceb,                -- 1-bit B port register enable 
input
      SSRA        => '0',                   -- 1-bit  A port Synchronous 
Set/Reset Input
      SSRB        => ssrb,                  -- 1-bit  B port Synchronous 
Set/Reset Input
      WEA         => "0000",                -- 4-bit  A port Write Enable 
Input
      WEB         => web );                 -- 4-bit  B port Write Enable 
Input

end Behavioral;


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library UNISIM;
use UNISIM.VComponents.all;
USE IEEE.STD_LOGIC_TEXTIO.ALL;
USE STD.TEXTIO.ALL;

ENTITY waveform IS
END waveform;

ARCHITECTURE testbench_arch OF waveform IS
    FILE RESULTS: TEXT OPEN WRITE_MODE IS "results.txt";

    COMPONENT bram9p
        PORT (
            clkb : In std_logic;
            enb : In std_logic;
            ssrb : In std_logic;
            regceb : In std_logic;
            addrb : In std_logic_vector (14 DownTo 0);
            web : In std_logic_vector (3 DownTo 0);
            doutb : Out std_logic_vector (31 DownTo 0)
        );
    END COMPONENT;

    SIGNAL clkb : std_logic := '0';
    SIGNAL enb : std_logic := '0';
    SIGNAL ssrb : std_logic := '0';
    SIGNAL regceb : std_logic := '0';
    SIGNAL addrb : std_logic_vector (14 DownTo 0) := "000000000000000";
    SIGNAL web : std_logic_vector (3 DownTo 0) := "0000";
    SIGNAL doutb : std_logic_vector (31 DownTo 0) := 
"UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU";

    SHARED VARIABLE TX_ERROR : INTEGER := 0;
    SHARED VARIABLE TX_OUT : LINE;

    constant PERIOD : time := 200 ns;
    constant DUTY_CYCLE : real := 0.5;
    constant OFFSET : time := 0 ns;

    BEGIN
        UUT : bram9p
        PORT MAP (
            clkb => clkb,
            enb => enb,
            ssrb => ssrb,
            regceb => regceb,
            addrb => addrb,
            web => web,
            doutb => doutb
        );

        PROCESS    -- clock process for clkb
        BEGIN
            WAIT for OFFSET;
            CLOCK_LOOP : LOOP
                clkb <= '0';
                WAIT FOR (PERIOD - (PERIOD * DUTY_CYCLE));
                clkb <= '1';
                WAIT FOR (PERIOD * DUTY_CYCLE);
            END LOOP CLOCK_LOOP;
        END PROCESS;

        PROCESS
            PROCEDURE CHECK_doutb(
                next_doutb : std_logic_vector (31 DownTo 0);
                TX_TIME : INTEGER
            ) IS
                VARIABLE TX_STR : String(1 to 4096);
                VARIABLE TX_LOC : LINE;
                BEGIN
                IF (doutb /= next_doutb) THEN
                    STD.TEXTIO.write(TX_LOC, string'("Error at time="));
                    STD.TEXTIO.write(TX_LOC, TX_TIME);
                    STD.TEXTIO.write(TX_LOC, string'("ns doutb="));
                    IEEE.STD_LOGIC_TEXTIO.write(TX_LOC, doutb);
                    STD.TEXTIO.write(TX_LOC, string'(", Expected = "));
                    IEEE.STD_LOGIC_TEXTIO.write(TX_LOC, next_doutb);
                    STD.TEXTIO.write(TX_LOC, string'(" "));
                    TX_STR(TX_LOC.all'range) := TX_LOC.all;
                    STD.TEXTIO.writeline(RESULTS, TX_LOC);
                    STD.TEXTIO.Deallocate(TX_LOC);
                    ASSERT (FALSE) REPORT TX_STR SEVERITY ERROR;
                    TX_ERROR := TX_ERROR + 1;
                END IF;
            END;
            BEGIN
                -- -------------  Current Time:  85ns
                WAIT FOR 85 ns;
                ssrb <= '1';
                addrb <= "000000000000001";
                -- -------------------------------------
                -- -------------  Current Time:  115ns
                WAIT FOR 30 ns;
                CHECK_doutb("00000000000000000000000000000011", 115);
                -- -------------------------------------
                -- -------------  Current Time:  285ns
                WAIT FOR 170 ns;
                ssrb <= '0';
                addrb <= "000000000000010";
                -- -------------------------------------
                -- -------------  Current Time:  485ns
                WAIT FOR 200 ns;
                enb <= '1';
                addrb <= "000000000000011";
                -- -------------------------------------
                -- -------------  Current Time:  515ns
                WAIT FOR 30 ns;
                CHECK_doutb("00000000000100000000000100010010", 515);
                -- -------------------------------------
                -- -------------  Current Time:  685ns
                WAIT FOR 170 ns;
                regceb <= '1';
                addrb <= "000000000000100";
                -- -------------------------------------
                -- -------------  Current Time:  885ns
                WAIT FOR 200 ns;
                addrb <= "000000000000101";
                -- -------------------------------------
                -- -------------  Current Time:  1085ns
                WAIT FOR 200 ns;
                regceb <= '0';
                addrb <= "000000000000110";
                -- -------------------------------------
                -- -------------  Current Time:  1285ns
                WAIT FOR 200 ns;
                enb <= '0';
                addrb <= "000000000000111";
                -- -------------------------------------
                -- -------------  Current Time:  1485ns
                WAIT FOR 200 ns;
                regceb <= '1';
                addrb <= "000000000001000";
                -- -------------------------------------
                -- -------------  Current Time:  1685ns
                WAIT FOR 200 ns;
                regceb <= '0';
                addrb <= "000000000001001";
                -- -------------------------------------
                -- -------------  Current Time:  1885ns
                WAIT FOR 200 ns;
                addrb <= "000000000001010";
                web <= "1111";
                -- -------------------------------------
                -- -------------  Current Time:  2085ns
                WAIT FOR 200 ns;
                enb <= '1';
                addrb <= "000000000001011";
                -- -------------------------------------
                -- -------------  Current Time:  2285ns
                WAIT FOR 200 ns;
                enb <= '0';
                regceb <= '1';
                addrb <= "000000000001100";
                -- -------------------------------------
                -- -------------  Current Time:  2485ns
                WAIT FOR 200 ns;
                regceb <= '0';
                addrb <= "000000000001101";
                -- -------------------------------------
                -- -------------  Current Time:  2685ns
                WAIT FOR 200 ns;
                addrb <= "000000000001110";
                web <= "0000";
                -- -------------------------------------
                -- -------------  Current Time:  2885ns
                WAIT FOR 200 ns;
                addrb <= "000000000001111";
                -- -------------------------------------
                -- -------------  Current Time:  3085ns
                WAIT FOR 200 ns;
                addrb <= "000000000010000";
                -- -------------------------------------
                -- -------------  Current Time:  3285ns
                WAIT FOR 200 ns;
                ssrb <= '1';
                addrb <= "000000000010001";
                -- -------------------------------------
                -- -------------  Current Time:  3485ns
                WAIT FOR 200 ns;
                ssrb <= '0';
                addrb <= "000000000010010";
                -- -------------------------------------
                -- -------------  Current Time:  3685ns
                WAIT FOR 200 ns;
                addrb <= "000000000010011";
                -- -------------------------------------
                -- -------------  Current Time:  3885ns
                WAIT FOR 200 ns;
                addrb <= "000000000010100";
                -- -------------------------------------
                -- -------------  Current Time:  4085ns
                WAIT FOR 200 ns;
                addrb <= "000000000010101";
                -- -------------------------------------
                -- -------------  Current Time:  4285ns
                WAIT FOR 200 ns;
                addrb <= "000000000010110";
                -- -------------------------------------
                -- -------------  Current Time:  4485ns
                WAIT FOR 200 ns;
                addrb <= "000000000010111";
                -- -------------------------------------
                -- -------------  Current Time:  4685ns
                WAIT FOR 200 ns;
                addrb <= "000000000011000";
                -- -------------------------------------
                -- -------------  Current Time:  4885ns
                WAIT FOR 200 ns;
                addrb <= "000000000011001";
                -- -------------------------------------
                WAIT FOR 315 ns;

                IF (TX_ERROR = 0) THEN
                    STD.TEXTIO.write(TX_OUT, string'("No errors or 
warnings"));
                    STD.TEXTIO.writeline(RESULTS, TX_OUT);
                    ASSERT (FALSE) REPORT
                      "Simulation successful (not a failure).  No problems 
detected."
                      SEVERITY FAILURE;
                ELSE
                    STD.TEXTIO.write(TX_OUT, TX_ERROR);
                    STD.TEXTIO.write(TX_OUT,
                        string'(" errors found in simulation"));
                    STD.TEXTIO.writeline(RESULTS, TX_OUT);
                    ASSERT (FALSE) REPORT "Errors found during simulation"
                         SEVERITY FAILURE;
                END IF;
            END PROCESS;

    END testbench_arch;