Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-4041-

VHDL issues

Name: Anonymous 2006-12-09 3:13

i'm making a cache for my VHDL class. problem is i'm a moron and apparently don't understand VHDL at all. so there is

    tag_ram: entity    work.tag_RAM(behav)
        port map(address => Paddress(9 downto 2),
            WRITE_ACTIVE_HIGH => NOTPRW,
            ENABLE => TAGENABLE,
            new_tag => Paddress(15 downto 10),
            tag => TAGDATAOUT);

but the only important part of this is that when TAGENABLE is high then TAGDATAOUT is supposed to end up with some value set to it, it does so through this piece of code:


    main : process(address, WRITE_ACTIVE_HIGH, ENABLE, new_tag) is
    begin
        if (WRITE_ACTIVE_HIGH = '0' and ENABLE = '1') --read
        then
            tag <= MEM(to_integer(address)) after 1 ns;
        end if;
        if (WRITE_ACTIVE_HIGH = '1' and ENABLE = '1') --write
        then
            MEM(to_integer(address)) <= new_tag after 1 ns;
        end if;
    end process main;


which for some reason never seems to figure out that TAGENABLE got set to one.  i have report statements in the real version of the code that basically suggest this code gets "stuck" before it can figure out that TAGENABLE went to one. if anyone knows enough about VHDL to guide me i'd be grateful.

Name: Anonymous 2006-12-09 3:39

How are you simulating this, the component by itself or a test bench?

Name: Anonymous 2006-12-09 3:56

i have a test bench. it is somewhat complicated. the cache itself makes use of two unclocked ram components, this tag being one of them. then i programmed out the cache and now i have a test bench that is pretending to to be the processor and the system (which the cache would normally act as a go-between for).

My comprehension of VHDL appears to be worse than i had thought.  Reports are revealing that my first attempt to give TAGENABLE a value of '1' after being initialized to '0' at startup are causing it to go 'X' (since i'm using STD_LOGIC datatypes).

I was reading in the VHDL cookbook that only one process is supposed to be allowed to drive a signal, but it didn't really elaborate on the consequences of failing to do so.  I have processes all over the place setting TAGENABLE, so if this is true i may be wholly screwed.

Name: Anonymous 2006-12-09 13:18

Yeah, that is your problem.  You need stick tristate buffers on all of the TAGENABLE inputs (i.e. use a multiplexer), so you can set everything to high impedance except for the input you are interested in at the time.  The 'X' in STD_LOGIC means that the value of TAGENABLE is unknown because you have multiple sources driving it.

Name: Anonymous 2006-12-09 14:33

i ended up making a really ugly fix by changing every different process's attempt to change TAGENABLE into its own variable and then having a main process model the behavior of the actual signal based on those 3 signals.

However this tristate buffer thing may be useful in the future, could you give a generic example in code (not necessarily my situation) to illustrate how one would do what you're describing? thanks in advance!

Name: Anonymous 2006-12-09 16:19

Sure, its a pretty simple component, something with a process like this:

process(buf_in, control) is
begin
     if(control = '0') then
          buf_out <= 'Z';
     elsif(control = '1') then
          buf_out <= buf_in;
     end if;
end process;

To make a 2-way multiplexer out of them, just take two of those, make a mux_control signal, connect it straight to the control of one buffer, and NOT it to the other's control.  Then connect the tri-state buffer outputs to the same multiplexer output.

Name: Anonymous 2006-12-09 20:25

ah ok, yeah that's a case very similar to muxes in class.  Basically i just wrote this thing really badly.  I had one function turning it on, a second function that was supposed to turn it off after that first function turned it on, and a third functoin that was turning it off and on for it's own reasons. the first and third functions were easily ORed together, the second function was what has been causing me headaches so far, though i think i got it.

Name: Anonymous 2006-12-10 0:48 (sage)

So is this what you hardware guys feel like with nontrivial examples in, say, C?

Name: OP 2006-12-10 2:00

actually it's kind of impossible to get good at hardware without also having a solid understanding of higher level programming.  In fact once i finish this cache and an assignment to synthesize an ALU using Leonardo, i have to write a simulator in C. 

It's going to require me reading in a netlist and then running a simulation.  part of it requires me to scan/lex and sadly the scanner and lexer i made way back in systems programming never worked very well to begin with.  does anyone have a recomendation for something i could easily include in Gcc?

Oh, and adding to the recent response, i do ok with basic C examples, but once you get to really abstract stuff like we did in software engineering this semester, i just get sick of it and want to go back to my wires and xor gates.


oh, and one more thing.  I've finally managed to get myself to the point where I'm writing data out of the ram, but unfortunately for the first couple calls nothing new is going to be written.  Essentially since the cache is starting off uninitialized the first couple mem calls will be empty and therefore right a string of 'U' to something that was already a string of 'U'.  So ye VHDL gurus plz halp me, i know that SIGNALNAME'active is supposed to trigger when the signal has activity even if you're setting it to the same value it already was, but for some reason:

wait until SIGNALNAME'active;

just hangs and never evaluates to true and subsequently progresses.  any suggestions for something else i might use? Basically i want this wait to be broken when the value of this signal is set even if it is set to the SAME value.  Many thanks in advance.

Name: Anonymous 2006-12-10 2:07

>>8
You should've picked a different language.  If "hardware guys" know a language it is likely to be either C or Fortran since they are lower-level and allow manipulations that are closer to hardware.

Name: OP 2006-12-10 2:27

>>10


honestly the issue isn't the language itself it's when you get into the more abstract and outlandish stuff. in particular, i find sorting algorithms baffling.  I understood the simple stuff and that was it.

But seriously could somebody help me with my coding issues?

Name: Anonymous 2006-12-10 2:29

>>9
Weird, 'active should be working, are you sure that your assignment statements are being made?

Name: OP 2006-12-10 3:25

        if (WRITE_ACTIVE_HIGH = '0' and ENABLE = '1') --read
        then

            report "**Tag ram returns address:" & to_string(address) & " with value:" & to_string(MEM(to_integer(address)));

            tag <= MEM(to_integer(address)) after 1 ns;
        end if;


of particular importance is that report, during the execution i get this report:

# ** Note: **Tag ram returns address:00110011 with value:UUUUUU
#    Time: 2 ns  Iteration: 1  Instance: /testbench/main_cache/tag_ram

where 00110011 is the address i have my testbench requesting, UUUUUU is the value in the memory (since this is the very first data request) and the tagdataout should also be UUUUUU at first. i am wondreing if maybe active does not handle assignments to "U" but only to 0 and 1 perhaps?

Name: Anonymous 2006-12-10 15:26

>>13
That seems likely, because it doesn't really make sense to say that you are assigning uninitialized to a value.  Why are you reading that memory address at the beginning in the first place?  Normally a system will automatically read address 0x0, which should contain the address of the first program instruction.

Name: Anonymous 2006-12-10 16:11

i find sorting algorithms baffling

quicksort [] = []
quicksort (x:xs) = quicksort (filter (< x) xs) ++ [x] ++ quicksort (filter (>= x) xs)


In a decent language sorting algorithms are easy to understand.

Name: Anonymous 2006-12-10 16:24

>>15
That's like saying notepad is better than vi/emacs because you can easily see how it works

Name: Anonymous 2006-12-10 16:46

>>15
That has nothing to do with understanding sorting algorithms, that is just an interface for using one.  If only the interface is taught, then we'll end up with programmers who won't even understand which is algorithm is best for a given situation, let alone know how to implement it.

Name: Anonymous 2006-12-10 17:02

>>17
What? That's the implementation, not the interface.

>>16
What?

Name: Anonymous 2006-12-10 17:12

>>15
you think "quicksort (filter (< x) xs) ++ [x] ++ quicksort (filter (>= x) xs)" is easy to understand? this is much easier to understand an probably a lot faster, too:
boolean quickSort(int *arr, int elements) {

  #define MAX_LEVELS 1000

  int  piv, beg[MAX_LEVELS], end[MAX_LEVELS], i=0, L, R ;

  beg[0]=0; end[0]=elements;
  while (i>=0) {
    L=beg[i]; R=end[i]-1;
    if (L<R) {
      piv=arr[L]; if (i==MAX_LEVELS-1) return false;
      while (L<R) {
        while (arr[R]>=piv && L<R) R--; if (L<R) arr[L++]=arr[R];
        while (arr[L]<=piv && L<R) L++; if (L<R) arr[R--]=arr[L]; }
      arr[L]=piv; beg[i+1]=L+1; end[i+1]=end[i]; end[i++]=L; }
    else {
      i--; }}
  return true; }

Name: Anonymous 2006-12-10 18:02

regardless of which you choose, i stand by my previous assertion that they confuse the hell out of me.  anyways, does anyone have some deeper insight on SIGNALNAME'active and SIGNALNAME'event ?  it seems like active is supposed to trigger on duplicate assignment (ie: if it was already zero and you set it to zero) but it seems like maybe it doesn't work for the uninitialized state "U"

Name: Anonymous 2006-12-10 18:05

>>18
If that is an implementation, then why didn't you paste the code for filter function that you wrote?

Name: Anonymous 2006-12-10 18:09

>>21
See >>14
I think I'm the only other VHDL person posting in this thread right now, not really sure what to tell you other than that fetching an uninitialized value from memory is not normal behavior.

Name: Anonymous 2006-12-10 18:48

>>19
lol that's a joke right

>>21
filter is part of the standard library in any decent language, but if you insist it looks something like this:

filter _ [] = []
filter p xs = [x | x <- xs, p x]


Or if you think using list comprehensions is cheating:

filter _ [] = []
filter p (x:xs)
    | p x = x:filter p xs
    | otherwise = filter p xs

Name: OP 2006-12-10 19:26

>>22

fair enough. as for the explanation, it is a cache that is starting out empty, so the first few times it accessess data there's nothing in the cache. if you put any value, even all 0s in you run the risk of mistaking it for an actual value.

However i worked around that particular problem by not waiting for activity on that signal and waiting on something else instead.

meanwhile, i am now having trouble with inout signals, for some reason if i have even only one process driving an inout signal it always comes out "U" but i can circumvent this issue by changing it to an in or out respectively (which hasn't cause funcitonal issues yet because the assignment only required us to do system reads, not system writes).

Can the other VHDL person on here explain inout to me? like special precautions i have to take in order to work with it?

Name: Anonymous 2006-12-10 19:46

>>24
Whenever I work with inouts, the only precaution I take is to use a pair of tristate buffers.  You attach the output of one to the inout (for writing), and the input of the other to the inout (for reading).  Then you do a multiplexer-like control signal, with the control going directly to one, and through a NOT to the other.  This lets you use a signal to control whether the inout is an in or an out.

Name: Anonymous 2006-12-10 20:44

>>25

that's probably what i need to do, but it strikes me as odd that when i was only doing assignment i was generating "U" even when the assignment was only occuring at one process. thanks much for your help btw. what do you use VHDL for? is it part of your job or are you a grad/undergrad?

Name: Anonymous 2006-12-10 21:31

>>26
Yeah, inouts can have some seemingly weird behaviors, especially when they are part of something like a realistic simulation of memory where you need to delay the write input and everything.  Right now I'm a 4th year Computer Engineering undergrad, just finished a class where I had to make a MIPS processor pipeline using a combination of VHDL and block diagrams.  I'm actually taking more Computer Science classes than Electrical Engineering, so VHDL has always felt like a programming language with a lot of restrictions and weird ways of doing things to me.

Name: Anonymous 2006-12-10 21:38

>>27


wow yeah that's exactly what i'm doing (4th year comp E) and i am likewise taking more CS than EE courses (although at my college it's all called EECS) although i'm dissapointed that i'm about to graduate and this is essentially the most in-depth program i've made yet.  I am taking a "computer design" lab next semester which is essentially VHDL without a teaching portion. however i was informed by someone who took it this semester that the final project was to model the states of a traffic light controller and took about 30 minutes.

Anyways, as one CE to another, where are you looking at working? are their any standout companies?

Name: Anonymous 2006-12-11 1:55

Yeah, there aren't any CpE professors here, just a director and her secretary to manage the students; all of my teachers are either CS or EE.  I've only taken a few VHDL courses, the last one was two years ago and started with us wiring gates by hand to satisfy a given equation.  We had to cut and strip the wires and then plug them into a bread board, and it took about 20-30 wires per equation.  Basically the professor's way of making us see how much better it is to do things in VHDL.

I'm actually planning to go to grad school for a masters degree in CS, and do some graphics research, but since I'm near Northern Virginia, most of my friends have gotten jobs at big companies like Northrop Grumman and Lockheed Martin.  I also know a few people getting big money at smaller companies, but it is on a trial basis, so they choose if they want to keep them after 6 months.  If you haven't already, apply to as many places as soon as you can until you start getting some interviews and call backs for second round interviews.

Name: OP 2006-12-11 3:11

yeah i had a class that consisted entirely of building things on a circuit board, that was a fun class.

Name: OP 2006-12-11 4:08

Holy fucking hell, i finally managed to get it to work. i offer it here to you in all its glory for you to marvel at and for nonhardware people to go "ZOMG!" before their heads explode:





library IEEE;
use IEEE.std_logic_1164.all;


use work.NUMERIC_SIGNED.all;


entity tag_RAM is
    port(address: in std_logic_vector(7 downto 0);
        WRITE_ACTIVE_HIGH, ENABLE: in std_logic;
        new_tag: in std_logic_vector(5 downto 0);
        tag: out std_logic_vector(5 downto 0));

type stdlogic_to_char_t is array(std_logic) of character;
    constant to_char : stdlogic_to_char_t := (
    'U' => 'U',
    'X' => 'X',
    '0' => '0',
    '1' => '1',
    'Z' => 'Z',
    'W' => 'W',
    'L' => 'L',
    'H' => 'H',
    '-' => '-');

type tag_memory is array(integer range <>) of std_logic_vector(5 downto 0);

function to_string(inp : std_logic_vector)
    return string
    is
    alias vec : std_logic_vector(1 to inp'length) is inp;
    variable result : string(vec'range);
    begin
    for i in vec'range loop
        result(i) := to_char(vec(i));
    end loop;
    return result;
    end;
end entity tag_ram;



architecture behav of tag_RAM is
signal MEM : tag_memory(255 downto 0);
signal STATE : std_logic_vector(1 downto 0);
begin

    main : process is
    begin
        if (WRITE_ACTIVE_HIGH = '0' and ENABLE = '1') --read
        then
            --report "**Tag ram returns address:" & to_string(address) & " with value:" & to_string(MEM(to_integer(address)));
            tag <= MEM(to_integer(address)) after 1 ns;
        end if;
        if (WRITE_ACTIVE_HIGH = '1' and ENABLE = '1') --write
        then
            --report "$$$TAG RAM wrote value: " & to_string(new_tag) & " to the address: " & to_string(address);
            MEM(to_integer(address)) <= new_tag after 1 ns;
        end if;
        if (ENABLE = '0')
        then
            tag <= "ZZZZZZ";
        end if;
        wait on address, WRITE_ACTIVE_HIGH, ENABLE, new_tag;
    end process main;

end architecture behav;

-----------------------------------------------------------

library IEEE;
use IEEE.std_logic_1164.all;


use work.NUMERIC_SIGNED.all;


entity main_RAM is
    port(address: in std_logic_vector(7 downto 0);
        WRITE_ACTIVE_HIGH, ENABLE: in std_logic;
        new_tag: in std_logic_vector(31 downto 0);
        tag: out std_logic_vector(31 downto 0));

type stdlogic_to_char_t is array(std_logic) of character;
    constant to_char : stdlogic_to_char_t := (
    'U' => 'U',
    'X' => 'X',
    '0' => '0',
    '1' => '1',
    'Z' => 'Z',
    'W' => 'W',
    'L' => 'L',
    'H' => 'H',
    '-' => '-');

type word_memory is array(integer range <>) of std_logic_vector(31 downto 0);

function to_string(inp : std_logic_vector)
    return string
    is
    alias vec : std_logic_vector(1 to inp'length) is inp;
    variable result : string(vec'range);
    begin
    for i in vec'range loop
        result(i) := to_char(vec(i));
    end loop;
    return result;
    end;
end entity main_RAM;

architecture behav of main_RAM is
signal MEM : word_memory(255 downto 0);
begin

    main : process(address, WRITE_ACTIVE_HIGH, ENABLE, new_tag) is
    begin
        if (WRITE_ACTIVE_HIGH = '0' and ENABLE = '1') --read
        then
            --report "!!!MEM RAM returning value: " & to_string(MEM(to_integer(address))) & "from address: " & to_string(address);
            tag <= MEM(to_integer(address)) after 1 ns;
        end if;
        if (WRITE_ACTIVE_HIGH = '1' and ENABLE = '1') --write
        then
            --report "^^^MEM RAM wrote value: " & to_string(new_tag) & " to the address: " & to_string(address);
            MEM(to_integer(address)) <= new_tag after 1 ns;
        end if;
        if (ENABLE = '0')
        then
            --report "%%MEM RAM GOING HIGH Z";
            tag <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" after 2 ns;
        end if;
    end process main;

end architecture behav;



----------------------------------

library IEEE;
use IEEE.std_logic_1164.all;


use work.NUMERIC_SIGNED.all;


entity cache is
    port ( Pstrobe, Prw, CLOCK : in std_logic;
        Paddress: in std_Logic_vector(15 downto 0);
        Sysaddress: out std_Logic_vector(15 downto 0);
        Sysdata: in std_logic_vector(7 downto 0);
        Pdata: out std_logic_vector(31 downto 0);
        Pready, Sysstrobe, Sysrw: out std_logic);

type stdlogic_to_char_t is array(std_logic) of character;
    constant to_char : stdlogic_to_char_t := (
    'U' => 'U',
    'X' => 'X',
    '0' => '0',
    '1' => '1',
    'Z' => 'Z',
    'W' => 'W',
    'L' => 'L',
    'H' => 'H',
    '-' => '-');

function to_string(inp : std_logic_vector)
    return string
    is
    alias vec : std_logic_vector(1 to inp'length) is inp;
    variable result : string(vec'range);
    begin
    for i in vec'range loop
        result(i) := to_char(vec(i));
    end loop;
    return result;
    end;
end entity cache;


architecture only of cache is
signal TAGENABLE, MEMENABLE : std_logic := '0' ;
signal TAGDATAOUT : std_logic_vector(5 downto 0);
signal NOTPRW : std_logic;
signal MEMDATA,MEMDATAOUT : std_logic_vector(31 downto 0);
signal CACHE_MISS : std_logic := '0' ;
signal OFFSET : std_logic_vector(1 downto 0) := "00" ;
signal SYSTEM_STROBE : std_logic := '0' ;
signal temp_data: std_logic_vector(31 downto 0);
signal P_ready_flag : std_logic;
signal PRDS_TAGENABLE : std_logic := '0';
signal PRDNS_TAGENABLE : std_logic := '1';
signal CRD_TAGENABLE : std_logic := '0' ;
signal MEMENABLE_1, MEMENABLE_2 : std_logic := '0' ;
signal Pready_1, Pready_2 : std_logic := '0' ;
signal TAG_WRITE, MEM_WRITE : std_logic := '0';
signal TALLY : std_logic_vector(2 downto 0) := "000" ;
begin


    tag_ram: entity    work.tag_RAM(behav)
        port map(address => Paddress(9 downto 2),
            WRITE_ACTIVE_HIGH => TAG_WRITE,
            ENABLE => TAGENABLE,
            new_tag => Paddress(15 downto 10),
            tag => TAGDATAOUT);

    main_ram: entity work.main_RAM(behav)
        port map(address => Paddress (9 downto 2),
            WRITE_ACTIVE_HIGH => MEM_WRITE,
            ENABLE => MEMENABLE,
            new_tag => MEMDATA,
            tag => MEMDATAOUT);

    INVPRW: process(Prw, CACHE_MISS) is
    begin
        NOTPRW <= (not Prw) or CACHE_MISS ;
    end process INVPRW;

    SET_TAG_ENABLE: process(CRD_TAGENABLE,PRDS_TAGENABLE) is
    begin
        if CRD_TAGENABLE = '1' or PRDS_TAGENABLE = '1'
        then
            TAGENABLE <= '1';
        else
            TAGENABLE <= '0';
        end if;
    end process;

    SET_MEM_ENABLE: process(MEMENABLE_1 , MEMENABLE_2) is
    begin
        if MEMENABLE_1 = '1' or MEMENABLE_2 = '1'
        then
            MEMENABLE <= '1';
        else
            MEMENABLE <= '0';
        end if;
    end process;

    SET_PREADY: process(Pready_1 , Pready_2) is
    begin
        if Pready_1 = '1' or Pready_2 = '1'
        then
            Pready <= '1';
        else
            Pready <= '0';
        end if;
    end process;


    PROCESSOR_REQUESTED_DATA: process is
    begin
        --report "waiting on pstrobe logic, current value is:" & to_char(Pstrobe);
        wait on Pstrobe;
        if (Pstrobe = '1')
        then
            --report "successfully called process: PROCESSOR_REQUESTED_DATA_SENSITIVE";
            PRDS_TAGENABLE <= '1' after 1 ns;
            wait until PRDS_TAGENABLE = '1';
       
            --report "waiting on TAGDATAOUT";
            --wait until TAGDATAOUT'active or TAGDATAOUT'event;
            wait until TAGENABLE = '1' and not (TAGDATAOUT = "ZZZZZZ");
           
           
            if (TAGDATAOUT = Paddress(15 downto 10))
            then         --cache hit
                report "++CACHE HIT";
                MEMENABLE_1 <= '1'after 1 ns;
                wait until MEMENABLE = '1';
                MEMENABLE_1 <= '0' after 2 ns;
                wait until MEMENABLE = '0' ;
                Pdata <= MEMDATAOUT after 1 ns;
                Pready_1 <= '1' after 1 ns;
                wait until CLOCK = '1';
                wait until CLOCK = '0';
                Pready_1 <= '0' after 1 ns;

                --report "End of Cache hit logic";

            else         --cache miss
                report "**CACHE MISS LOGIC";
                TALLY <= TALLY + 1;
                OFFSET <= "00" after 1 ns;
                CACHE_MISS <= '1' after 1 ns;
                wait until CACHE_MISS = '1';
            end if;
            --report "Finished cache miss/hit logic, value of PRDS_TAGENABLE:" & to_char(PRDS_TAGENABLE);
            PRDS_TAGENABLE <= '0' after 1 ns;
            wait until PRDS_TAGENABLE = '0';
            --report "changed PRDS_TAGENABLE";
        end if;
        --report "++finished Pstrobe logic";
        if (CACHE_MISS = '1')
        then
           
            --report "successfully called process: CACHE_MISS";
            --report "Cache miss #" & to_string(TALLY) & " is confirmed system strobe is:" & to_char(SYSTEM_STROBE);
            Sysrw <= '1' after 1 ns;    --read
            Sysaddress <= Paddress + OFFSET after 1 ns;
            Sysstrobe <= '1' after 1 ns;
            SYSTEM_STROBE <= '1' after 1 ns;
            CACHE_MISS <= '0' after 1 ns;
            wait until SYSTEM_STROBE = '1';
            --report "end of cache miss logic for cache miss #" & to_string(TALLY);       
        end if;

        --report "just prior to system strobe logic";   
if (SYSTEM_STROBE = '1')
then
        --report "begin SYSTEM STROBE logic for cache miss #" & to_string(TALLY);
        wait until CLOCK = '0';
        Sysstrobe <= '0' after 1 ns;
        SYSTEM_STROBE <= '0' after 1 ns;
        wait until CLOCK = '1';
        temp_data(7 downto 0) <= Sysdata after 1 ns;
       
        Sysaddress <= Paddress + "01" after 1 ns;
       
       
        wait until CLOCK = '0';
        wait until CLOCK = '1';
        temp_data(15 downto 8) <= Sysdata after 1 ns;
       
        Sysaddress <= Paddress + "10" after 1 ns;
       
       
        wait until CLOCK = '0';
        wait until CLOCK = '1';
        temp_data(23 downto 16) <= Sysdata after 1 ns;
       
        Sysaddress <= Paddress + "11" after 1 ns;
       
       
        wait until CLOCK = '0';
        wait until CLOCK = '1';
        Pdata(31 downto 24) <= Sysdata after 1 ns;
       
        Pdata(23 downto 0) <= temp_data(23 downto 0) after 1 ns;
        Pready_2 <= '1' after 1 ns;       

        --write new value to cache
        MEMDATA(31 downto 24) <= Sysdata after 1 ns;
        MEMDATA(23 downto 0) <= temp_data(23 downto 0) after 1 ns;
        MEMENABLE_2 <= '1' after 1 ns;
        MEM_WRITE <= '1' after 1 ns;
       
        --write new tag
        CRD_TAGENABLE <= '1' after 1 ns;
        TAG_WRITE <= '1' after 1 ns;

        wait until TAGENABLE = '1' and MEMENABLE = '1';
        CRD_TAGENABLE <= '0' after 1 ns;
        TAG_WRITE <= '0' after 1 ns;
        MEM_WRITE <= '0' after 1 ns;
        MEMENABLE_2 <= '0' after 1 ns;

        --Pready wait time
        wait until CLOCK = '0';
        wait until CLOCK = '1';
        --report "((setting pready to 0";
        Pready_2 <= '0' after 1 ns;
end if;
        --report "after system strobe logic CACHE_MISS:" & to_char(CACHE_MISS) & " Pstrobe: " & to_char(Pstrobe);
       
        if CACHE_MISS = '1'
        then
            --report "conditional wait cache miss, current: " & to_char(CACHE_MISS);
            wait until CACHE_MISS = '0';
        end if;
        if Pstrobe = '1'
        then
            --report "conditional wait Pstrobe, current: " & to_char(Pstrobe);
            wait until Pstrobe = '0';
        end if;
        --report "after conditional waits CACHE_MISS:" & to_char(CACHE_MISS) & " Pstrobe: " & to_char(Pstrobe);
    end process PROCESSOR_REQUESTED_DATA;

end architecture only;

--report "###Value pulled from Sysdata: " & to_string(Sysdata);
-----------------------------------------------------------------


library IEEE;
use IEEE.std_logic_1164.all;


use work.NUMERIC_SIGNED.all;


entity testbench is
type stdlogic_to_char_t is array(std_logic) of character;
    constant to_char : stdlogic_to_char_t := (
    'U' => 'U',
    'X' => 'X',
    '0' => '0',
    '1' => '1',
    'Z' => 'Z',
    'W' => 'W',
    'L' => 'L',
    'H' => 'H',
    '-' => '-');

function to_string(inp : std_logic_vector)
    return string
    is
    alias vec : std_logic_vector(1 to inp'length) is inp;
    variable result : string(vec'range);
    begin
    for i in vec'range loop
        result(i) := to_char(vec(i));
    end loop;
    return result;
    end;
end entity testbench;


architecture main of testbench is
signal PROCESSOR_STROBE : std_logic;
signal PROCESSOR_READ_WRITE : std_logic := '1'; --since we never write
signal MAIN_CLOCK : std_logic;
signal PROCESSOR_ADDRESS : std_logic_vector(15 downto 0);
signal SYSTEM_ADDRESS : std_logic_vector(15 downto 0);
signal SYSTEM_DATA: std_logic_vector(7 downto 0);
signal PROCESSOR_DATA: std_logic_vector(31 downto 0);
signal PROCESSOR_READY, SYSTEM_STROBE, SYSTEM_READ_WRITE: std_logic;
begin

    main_cache: entity work.cache(only)
    port  map ( Pstrobe => PROCESSOR_STROBE,
            Prw => PROCESSOR_READ_WRITE,
            CLOCK => MAIN_CLOCK,
            Paddress => PROCESSOR_ADDRESS,
            Sysaddress => SYSTEM_ADDRESS,
            Sysdata => SYSTEM_DATA,
        Pdata => PROCESSOR_DATA,
        Pready => PROCESSOR_READY,
        Sysstrobe => SYSTEM_STROBE,
        Sysrw => SYSTEM_READ_WRITE);

    CLOCKING: process is
    begin
        MAIN_CLOCK <= '1';
        wait for 50 ns;
        MAIN_CLOCK <= '0';
        wait for 50 ns;
        --report "====clock cycle====";
    end process;

    FAKE_SYSTEM_BUS: process is
    begin
        wait until SYSTEM_STROBE = '1';

        SYSTEM_DATA <= "X0000000" after 1 ns;
        wait until MAIN_CLOCK = '0';
        wait until MAIN_CLOCK = '1';
       

        SYSTEM_DATA(7 downto 4) <= PROCESSOR_ADDRESS(5 downto 2) after 1 ns;
        SYSTEM_DATA(3 downto 0) <= PROCESSOR_ADDRESS(5 downto 2) after 1 ns;
        wait until MAIN_CLOCK = '0';
        wait until MAIN_CLOCK = '1';


        SYSTEM_DATA(7 downto 4) <= PROCESSOR_ADDRESS(5 downto 2) after 1 ns;
        SYSTEM_DATA(3 downto 0) <= PROCESSOR_ADDRESS(5 downto 2) after 1 ns;
        wait until MAIN_CLOCK = '0';
        wait until MAIN_CLOCK = '1';
       

        SYSTEM_DATA <= "0000000X" after 1 ns;
        wait until MAIN_CLOCK = '0';
        wait until MAIN_CLOCK = '1';

        SYSTEM_DATA <= "ZZZZZZZZ" after 1 ns;

        if SYSTEM_STROBE = '1'
        then
            wait until SYSTEM_STROBE = '0';
        end if;
    end process;
       
    --report "~~~Setting value of sysdata:" & to_string(SYSTEM_DATA);
   

    DATA_REQUEST_MAIN_PROCESS : process is
    begin
        wait until MAIN_CLOCK = '1';
       
        --51
        PROCESSOR_ADDRESS <= "0000000011001100" after 1 ns;
        PROCESSOR_STROBE <= '1' after 1 ns;
        wait until PROCESSOR_READY = '1';
        report "*****from 51: " & to_string(PROCESSOR_DATA);
        PROCESSOR_STROBE <= '0' after 1 ns;
        wait until PROCESSOR_READY = '0';

        --57
        PROCESSOR_ADDRESS <= "0000000011100100" after 1 ns;
        PROCESSOR_STROBE <= '1' after 1 ns;
        wait until PROCESSOR_READY = '1';
        report "*****from 57: " & to_string(PROCESSOR_DATA);
        PROCESSOR_STROBE <= '0' after 1 ns;
        wait until PROCESSOR_READY = '0';

        --58
        PROCESSOR_ADDRESS <= "0000000011101000" after 1 ns;
        PROCESSOR_STROBE <= '1' after 1 ns;
        wait until PROCESSOR_READY = '1';
        report "*****from 58: " & to_string(PROCESSOR_DATA);
        PROCESSOR_STROBE <= '0' after 1 ns;
        wait until PROCESSOR_READY = '0';

        --59
        PROCESSOR_ADDRESS <= "0000000011101100" after 1 ns;
        PROCESSOR_STROBE <= '1' after 1 ns;
        wait until PROCESSOR_READY = '1';
        report "*****from 59: " & to_string(PROCESSOR_DATA);
        PROCESSOR_STROBE <= '0' after 1 ns;
        wait until PROCESSOR_READY = '0';

        --57
        PROCESSOR_ADDRESS <= "0000000011100100" after 1 ns;
        PROCESSOR_STROBE <= '1' after 1 ns;
        wait until PROCESSOR_STROBE = '1';
        PROCESSOR_STROBE <= '0' after 1 ns;
        --report "57 cache hit is waiting for Pready";
        wait until PROCESSOR_READY = '1';
        report "*****from 57: " & to_string(PROCESSOR_DATA);

        wait until PROCESSOR_READY = '0';
        --report "~~PROCESSR_READY successfully lowered after first cache hit, pstrobe is" & to_char(PROCESSOR_STROBE);

        --51
        PROCESSOR_ADDRESS <= "0000000011001100" after 1 ns;
        PROCESSOR_STROBE <= '1' after 1 ns;
        wait until PROCESSOR_STROBE = '1';
        --report "first assignment post cache hit to processor strobe completed";
        wait until PROCESSOR_READY = '1';

        report "*****from 51: " & to_string(PROCESSOR_DATA);
        PROCESSOR_STROBE <= '0' after 1 ns;
        wait until PROCESSOR_READY = '0';

        wait until PROCESSOR_READY = '1';
       
   
    end process;

end architecture main;

Name: Anonymous 2006-12-11 15:57

RAM GOING HIGH Z!!!!

Name: OP 2006-12-12 1:32

it's an important thing to be aware of :-P

Name: Anonymous 2006-12-12 10:12

>>9
Yeah, that's what I meant really. As a software guy myself, I once tried to write a simple UART in Verilog and... well... let's say I totally failed at it. The feeling must've been like someone who doesn't know assembler trying to understand what's going on with all the pointers and shit like that in C...

Name: Anonymous 2009-01-14 12:55

LISP

Name: Anonymous 2010-12-06 9:05

Back to /b/, ``GNAA Faggot''

Name: Sgt.Kabu뿀젼kiman⥣ꇄ 2012-05-28 21:11

Bringing /prog/ back to its people
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy

Don't change these.
Name: Email:
Entire Thread Thread List