GIDForums  

Go Back   GIDForums > Computer Programming Forums > Miscellaneous Programming Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 22-Apr-2009, 12:04
mbrook10 mbrook10 is offline
New Member
 
Join Date: Apr 2009
Posts: 3
mbrook10 is on a distinguished road

VHDL Programming help


I'm building a simple processor that does pipe lining. I wanted to know if there is anyway I can call a component I made in another file within a case statement. Here's some of my code.

architecture behv of MEM is

COMPONENT CPU_Memory
port(
inData : in std_logic_vector(31 downto 0);
address : in std_logic_vector(31 downto 0);
read : in std_logic;
write : in std_logic;
clk : in std_logic;
enable : in std_logic;
outData : out std_logic_vector(31 downto 0)
);
end COMPONENT;
signal BLANK: std_logic_vector(31 downto 0);
begin

BLANK <= std_logic_vector(to_unsigned(0, 31));
process
begin
case opcode is
when "010000" => --LW
-- access "address" and output "outData"
MEMLW: Memory
portmap(BLANK,in_address,'1','0',clk,'1',outRead);


When I call port map within my case statement I get an error saying illegal sequential statement. I wanted to know if there was another way around it.
  #2  
Old 22-Apr-2009, 17:57
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 5,218
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: VHDL Programming help


Quote:
Originally Posted by mbrook10
...
When I call port map within my case statement I get an error...

First of all, I don't know that the "portmap" function is supposed to do. In VHDL a Port Map statement binds local signals to the component that is being instantiated.

Secondly, if you have previously compiled a vhdl Entity/Architecture into the working library, then components are combined "automatically." I wouldn't say that it is "calling" the component; I would say that it is instantiating the component. Think of a piece of hardware. You have components in a bin in a cabinet. You pick a component out of the bin and solder it to your circuit board. In VHDL, you describe the connections between "parent" signals on the circuit board and "component" signal pins with a Port Map statement.

I'll summarize a possible plan of attack based on the way that I do things.

Let's assume that I am creating the source of the VHDL other than "std" and "ieee" standard library components supplied by the vendor.

Furthermore, let's suppose that each entity/architecture that I create is in a separate file. It is possible to have more than one entity/architecture in a single file, and it is possible to have more than one architecture for a given entity. There are several ways to pass the configuration information to the VHDL compiler/simulator but I always start out with the simplest stuff so that default library components are always used.

I always make the source file name correspond to the entity in that file.

So---here's the drill:

Suppose I am going to build a memory named "mem". It uses a component named "cpu_memory"

I design from the top down, but I implement from the bottom up, so, after defining the components that I am going to implement and defining their connectedness, I start with the lowest component and work my way up, compiling and testing as I go.

So, for this problem the first thing that I do is to create a text file named cpu_memory.vhd

I put the entity and architecture in it.


The cpu_memory file might look like this:
Code:
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY cpu_memory IS PORT(indata : IN std_logic_vector(31 DOWNTO 0); address : IN std_logic_vector(31 DOWNTO 0); read : IN std_logic; write : IN std_logic; clk : IN std_logic; enable : IN std_logic; outdata : OUT std_logic_vector(31 DOWNTO 0) ); END cpu_memory; ARCHITECTURE rtl OF cpu_memory IS BEGIN -- Put stuff here to implement the functionality END rtl;

If I want to test this by itself, I make a testbench file, named test_cpu_memory.vhd. It instantiates a "cpu_memory" component and has code that stimulates the memory and maybe tests for validity. I'll leave the details for you.

Next, I create a file named "mem.vhd" that instantiates a cpu_memory component and connects the "mem" I/O to the "cpu_memory" component.
The "mem.vhd" file might look like:

Code:
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY mem is PORT (opcode : IN std_logic_vector(5 DOWNTO 0); addr : IN std_logic_vector(31 DOWNTO 0); datin : IN std_logic_vector(31 DOWNTO 0); ena : IN std_logic; clk : IN std_logic; datout : OUT std_logic_vector(31 DOWNTO 0) ); END mem; ARCHITECTURE behavorial OF mem IS COMPONENT cpu_memory PORT(indata : IN std_logic_vector(31 DOWNTO 0); address : IN std_logic_vector(31 DOWNTO 0); read : IN std_logic; write : IN std_logic; clk : IN std_logic; enable : IN std_logic; outdata : OUT std_logic_vector(31 DOWNTO 0) ); END COMPONENT; SIGNAL readmem : std_logic; SIGNAL writemem : std_logic; BEGIN i_cpu_memory: cpu_memory PORT MAP (indata => datin, address => addr, read => readmem, write => writemem, clk => clk, enable => ena, outdata => datout ); gen_control_sigs: process(opcode) BEGIN CASE opcode IS WHEN "010000" => --LW readmem <= '1'; writemem <= '0'; -- WHEN "??????" op code for writing -- WHEN "??????" other op codes? WHEN OTHERS => readmem <= '0'; writemem <= '0'; END CASE; END PROCESS gen_control_sigs; -- -- Other stuff that may be needed to create a memory cycle -- END behavorial;

Now I compile this file. If the compiler complains, I fix it.

Finally, in preparation for simulation, I create a file named "test_mem.vhd" that instantiates a "mem" component and generates stimulus signals for it.


Etc.


Notes on style:

1. I always (yes always) use the form of port map that explicitly lists the signals rather than depending on the form that depends on the order of the port signals. Do it the "easy" way if you want to save some typing, but be prepared to spend lots of time debugging things that are due to problems that arise when you add or remove a port signal during later editing and lose track of what goes where. Spell it out! That's the ticket.

2. If every component that you use has one architecture for each entity, you don't need any configuration information other than the port map. If you make any changes in the lower-level components, recompile them first, then recompile anything in your design that uses them. I generally create a Makefile (using ModelSim vmake) that allows a "make" utility program to take care of re-compiling things automatically when changes are made to any library component. This gets to be important when designs have more than a few components. For now you can just do it manually.

3. As I show in my example, I always give processes names. I have found that without this, simulations can get very confusing. For example, trying to trace variable names inside processes can get confusing if you are single-stepping the simulator and don't know what process you are in at the time.

4. Unless it's for some special "proof-of-concept" model, I am almost always presented with projects for which the components must be synthesizable, so I follow certain rules about what kind of VHDL goes into the models. My designs themselves are just about always based on synchronous logic, at least at the top level. Again, this determines what goes inside the models. The language and simulators can handle a very wide range of other interesting things, but logic design (and real-world synthesis) is where I am at. Of course, testbench programs may be just for simulation and generally they can (and do) contain non-synthesizable constructs.

Not everyone does things this way, and that's All Right With Me. I just thought I would throw a few things out there for your consideration.

If my examples don't really suit your needs (that is, they don't address whatever problem you are having), then give us some more information.

Show a complete file that you are trying to compile (simplified if necessary). If you are using non-standard (non-ieee for example) library functions, show us what they are.

Regards,

Dave
Last edited by davekw7x : 22-Apr-2009 at 18:43.
  #3  
Old 24-Apr-2009, 12:22
mbrook10 mbrook10 is offline
New Member
 
Join Date: Apr 2009
Posts: 3
mbrook10 is on a distinguished road

Re: VHDL Programming help


Thanks a lot. I have one more question. Do you know as to why I;m getting all U's on my array vector. Part of my code is below.

How do you initialize an array of vectors. I tried doing it and for some reason nothing in my array is not being set. Below is part of my code.

architecture behv of CPU_Memory is
type memory is array(0 to 1023) of std_logic_vector(7 downto 0);
signal memory_address : memory;
begin
memory_address(0) <= "00000000";
memory_address(1) <= "00000000";
memory_address(1) <= "00000000";
memory_address(3) <= "00000000";
process(datain, address, rd, wr, clk, en)
variable index: integer;
begin
if(clk = '1' and en = '1') then
index := conv_integer(address);
if(rd = '1') then
dataout(31 downto 24) <= memory_address(index);
dataout(23 downto 16) <= memory_address(index+1);
dataout(15 downto 8 ) <= memory_address(index+2);
dataout(7 downto 0) <= memory_address(index+3);
.....
....
....
...
When I run a testbench and see what is in memory_address (0), 1, 2, and 3 it returns all U's.
  #4  
Old 24-Apr-2009, 19:12
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 5,218
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: VHDL Programming help


Quote:
Originally Posted by mbrook10
Thanks a lot. I have one more question. Do you know as to why I;m getting all U's on my array vector. Part of my code is below.
Without seeing all of your code, including the testbench, how could anyone guess what's going wrong in your design?

Here's how I might get started, with partially functional components:

Code:
-- -- cpu_memory.vhd -- LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_unsigned.ALL; -- -- a 1k Byte memory accessed as 256 32-bit words??? ENTITY cpu_memory IS PORT ( address : IN std_logic_vector(7 DOWNTO 0); ena : IN std_logic; rd : IN std_logic; clk : IN std_logic; dataout : OUT std_logic_vector(31 DOWNTO 0) ); END cpu_memory; ARCHITECTURE behavorial OF cpu_memory IS -- -- -- TYPE memory_t IS ARRAY(0 TO 1023) OF STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL memory : memory_t; BEGIN -- -- by assigning memory values here, the contents can't -- change memory(0) <= "00000001"; memory(1) <= "00000010"; memory(2) <= "00000011"; memory(3) <= "00000100"; -- -- Synchronous memory access -- Dataout is latched by the rising edge of the clock -- gen_dataout: PROCESS(clk) VARIABLE index: INTEGER; BEGIN IF(rising_edge(clk)) THEN IF ena = '1' THEN index := conv_integer(address & "00"); IF(rd = '1') THEN dataout(31 DOWNTO 24) <= memory(index); dataout(23 DOWNTO 16) <= memory(index+1); dataout(15 DOWNTO 8 ) <= memory(index+2); dataout(7 DOWNTO 0) <= memory(index+3); END IF; END IF; END IF; END PROCESS gen_dataout; END behavorial;

Code:
-- -- test_cpu_memory.vhd -- LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_unsigned.ALL; ENTITY test_cpu_memory IS END test_cpu_memory; ARCHITECTURE tb OF test_cpu_memory IS COMPONENT cpu_memory PORT ( address : IN std_logic_vector(7 DOWNTO 0); ena : IN std_logic; rd : IN std_logic; clk : IN std_logic; dataout : OUT std_logic_vector(31 DOWNTO 0) ); END COMPONENT; SIGNAL address: std_logic_vector(7 DOWNTO 0) := (OTHERS => '0'); SIGNAL ena : std_logic := '0'; SIGNAL rd : std_logic := '0'; SIGNAL clk : std_logic := '0'; SIGNAL dataout: std_logic_vector(31 DOWNTO 0); BEGIN i_cpu_memory: cpu_memory PORT MAP(address => address, ena => ena, rd => rd, clk => clk, dataout => dataout ); gen_stimulus: PROCESS BEGIN rd <= '1'; ena <= '1'; WAIT FOR 1 us; clk <= '1'; WAIT FOR 1 us; clk <= '0'; WAIT; END PROCESS gen_stimulus; END tb;

Regards,

Dave
  #5  
Old 25-Apr-2009, 23:17
mbrook10 mbrook10 is offline
New Member
 
Join Date: Apr 2009
Posts: 3
mbrook10 is on a distinguished road

Re: VHDL Programming help


Thanks a lot. I got the memory address to update and got my simple processor working. Hopefully I get a good grade on it. All of your posts were very helpful.
 
 

Recent GIDBlogToyota - 2009 May Promotion by Nihal

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Looking for opinions crystalattice Miscellaneous Programming Forum 6 27-Sep-2006 22:02
VHDL programming anyone? aijazbaig1 Miscellaneous Programming Forum 11 09-Aug-2006 09:28
printer / font color / windows programming nicolas_qc MS Visual C++ / MFC Forum 0 04-Jan-2006 00:13
[Tutorial] GUI programming with FLTK dsmith FLTK Forum 10 03-Oct-2005 16:41
GUI programming crystalattice C++ Forum 5 14-Sep-2004 13:17

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 01:09.


vBulletin, Copyright © 2000 - 2009, Jelsoft Enterprises Ltd.