From: KMS on 16 Jan 2010 12:59 On Dec 1 2009, 11:53 am, "glallenjr" <glalle...(a)gmail.com> wrote: > Currently I am studying the "Circuit Design with VHDL" by Volnei A. > Pedroni. On page 207 the run a simulation but do not provide the test > bench. I would like to run the same simulation but I am not familiar with > how to write a testbench. If possible please provide a testbench to mimic > the simulation shown on page 207. If you are unfamiliar with this book or > the simulation run, I would also appreciate ANY KIND of testbench which > could simulate it's funcionality. Also if there are any errors with the > code, please let me know! Your help is much appreciated! thank you! > > Here is the code we are trying to implement: > > library IEEE; > use IEEE.STD_LOGIC_1164.ALL; > > entity vending_machine is > Port ( clk, rst : IN STD_LOGIC; > nickel_in, dime_in, quarter_in : IN BOOLEAN; > candy_out, nickel_out, dime_out, quarter_out: OUT STD_LOGIC); > end vending_machine; > > architecture fsm of vending_machine IS > TYPE state IS (st0, st5, st10, st15, st20, st25, st30, st35, st40, st45); > SIGNAL present_state, next_state: STATE; > > begin > PROCESS(rst, clk) > BEGIN > IF(rst='1') THEN > present_state <=st0; > ELSIF(clk' EVENT AND clk ='1') THEN > present_state <= next_state; > END IF; > END PROCESS; > > PROCESS(present_state, nickel_in, dime_in, quarter_in) > BEGIN > CASE present_state IS > WHEN st0 => > candy_out <= '0'; > nickel_out <='0'; > dime_out <= '0'; > IF (nickel_in) THEN next_state <= st5; > ELSIF (dime_in) THEN next_state <= st10; > ELSIF (quarter_in) THEN next_state <= st25; > ELSE next_state <=st0; > END IF; > WHEN st5 => > candy_out <= '0'; > nickel_out <='0'; > dime_out <= '0'; > IF (nickel_in) THEN next_state <= st10; > ELSIF (dime_in) THEN next_state <= st15; > ELSIF (quarter_in) THEN next_state <= st30; > ELSE next_state <=st5; > END IF; > WHEN st10 => > candy_out <= '0'; > nickel_out <='0'; > dime_out <= '0'; > IF (nickel_in) THEN next_state <= st15; > ELSIF (dime_in) THEN next_state <= st20; > ELSIF (quarter_in) THEN next_state <= st35; > ELSE next_state <=st10; > END IF; > WHEN st15 => > candy_out <= '0'; > nickel_out <='0'; > dime_out <= '0'; > IF (nickel_in) THEN next_state <= st20; > ELSIF (dime_in) THEN next_state <= st25; > ELSIF (quarter_in) THEN next_state <= st40; > ELSE next_state <=st15; > END IF; > WHEN st20 => > candy_out <= '0'; > nickel_out <='0'; > dime_out <= '0'; > IF (nickel_in) THEN next_state <= st25; > ELSIF (dime_in) THEN next_state <= st30; > ELSIF (quarter_in) THEN next_state <= st45; > ELSE next_state <=st20; > END IF; > WHEN st25 => > candy_out <= '1'; > nickel_out <='0'; > dime_out <= '0'; > next_state <= st0; > WHEN st30 => > candy_out <= '1'; > nickel_out <='1'; > dime_out <= '0'; > next_state <= st0; > WHEN st35 => > candy_out <= '1'; > nickel_out <='0'; > dime_out <= '1'; > next_state <= st35; > WHEN st45 => > candy_out <= '0'; > nickel_out <='0'; > dime_out <= '1'; > next_state <= st35; > END CASE; > END PROCESS; > > END fsm; > > --------------------------------------- > This message was sent using the comp.arch.fpga web interface onhttp://www..FPGARelated.com Hi, I recommend you change your BOOLEANs to STD_LOGIC. Also, assuming this is targeting real hardware, remember that the insertion of coins is asynchronous and this is a synchronous design. You'll need some logic for metastability and to create a one clock-wide pulse to your state machine. You can do something like this for a testbench: ===================== library ieee; use ieee.std_logic_1164.all; -- Add your library and packages declaration here ... entity vending_machine_tb is end vending_machine_tb; architecture TB_ARCHITECTURE of vending_machine_tb is -- Component declaration of the tested unit component vending_machine port ( clk : in std_logic; rst : in std_logic; nickel_in : in std_logic; dime_in : in std_logic; quarter_in : in std_logic; candy_out : out std_logic; nickel_out : out std_logic; dime_out : out std_logic; quarter_out : out std_logic ); end component; -- Stimulus signals - signals mapped to the input and inout ports of tested entity signal clk : std_logic := '0'; signal rst : std_logic := '0'; signal nickel_in : std_logic := '0'; signal dime_in : std_logic := '0'; signal quarter_in : std_logic := '0'; -- Observed signals - signals mapped to the output ports of tested entity signal candy_out : std_logic; signal nickel_out : std_logic; signal dime_out : std_logic; signal quarter_out : std_logic; -- Add your code here ... begin -- Unit Under Test port map UUT : vending_machine port map ( clk => clk, rst => rst, nickel_in => nickel_in, dime_in => dime_in, quarter_in => quarter_in, candy_out => candy_out, nickel_out => nickel_out, dime_out => dime_out, quarter_out => quarter_out ); -- Add your stimulus here ... clk <= not clk after 50ns; Stimulus: process begin wait for 200 ns; rst <='1'; wait for 200 ns; rst <='0'; wait for 200 ns; nickel_in <='1'; wait for 1 us; nickel_in <='0'; wait for 1 us; dime_in <='1'; wait for 1 us; dime_in <='0'; wait for 1 us; quarter_in <='1'; wait for 1 us; quarter_in <='0'; -- add more... wait; end process; end TB_ARCHITECTURE; configuration TESTBENCH_FOR_vending_machine of vending_machine_tb is for TB_ARCHITECTURE for UUT : vending_machine use entity work.vending_machine(fsm); end for; end for; end TESTBENCH_FOR_vending_machine; ================== I didn't simulate your design to check its operation. This TB is simple but it will get you started. KMS
From: Gabor on 16 Jan 2010 22:23 On Jan 16, 12:59 pm, KMS <kms34...(a)gmail.com> wrote: > Hi, > > I recommend you change your BOOLEANs to STD_LOGIC. If you change the booleans to std_logic, you'll need to change all the if statements to have a comparison operator like if (nickel_in) then . . . becomes if (nickel_in = '1') then . . . If you're not trying to synthesize this logic, I'm not really clear why you shouldn't use booleans, but then I would normally have used Verilog. On the other hand, if you make the code synthesizable, you can use the Xilinx webpack to generate a testbench template automatically. That often saves the headache of writing the signal declarations, instantiations and initialization logic. Regards, Gabor
From: KJ on 17 Jan 2010 13:28 > On Jan 16, 10:23 pm, Gabor <ga...(a)alacron.com> wrote: > to generate a testbench > template automatically. That often saves the headache > of writing the signal declarations, instantiations and > initialization logic. > I never caught on to how this was ever much of a headache and why it gets touted by the tool vendors as something important. Copy/paste the entity that you create to make two copies. The first copy you add the word 'signal' at the begining of the line and then delete the 'in', 'out' and 'inout' modes from each line and 'presto' you have the signal definitions for the testbench. The second copy you edit the 'entity' line to make it an instantiation, change 'generic' and 'port' to 'generic map' and 'port map' and then use a macro to change all of the lines of the entity from this... xyz: in std_logic; ....to this... xyz => xyz, Touch it up a bit if you want and you're done...depends on your preferred editor, but it never takes more than a minute or so. Not much of a time saver in my opinion. Now something to generate the actual stimulus and generate the assertion checking would be nice and would be a real timesaver... KJ
From: Gabor on 17 Jan 2010 13:55 On Jan 17, 1:28 pm, KJ <kkjenni...(a)sbcglobal.net> wrote: > > On Jan 16, 10:23 pm, Gabor <ga...(a)alacron.com> wrote: > > to generate a testbench > > template automatically. That often saves the headache > > of writing the signal declarations, instantiations and > > initialization logic. > > I never caught on to how this was ever much of a headache and why it > gets touted by the tool vendors as something important. Copy/paste > the entity that you create to make two copies. > > The first copy you add the word 'signal' at the begining of the line > and then delete the 'in', 'out' and 'inout' modes from each line and > 'presto' you have the signal definitions for the testbench. > > The second copy you edit the 'entity' line to make it an > instantiation, change 'generic' and 'port' to 'generic map' and 'port > map' and then use a macro to change all of the lines of the entity > from this... > > xyz: in std_logic; > > ...to this... > > xyz => xyz, > > Touch it up a bit if you want and you're done...depends on your > preferred editor, but it never takes more than a minute or so. > > Not much of a time saver in my opinion. Now something to generate the > actual stimulus and generate the assertion checking would be nice and > would be a real timesaver... > > KJ Well just your description is significanly longer than the buttons to generate the testbench in ISE. It's actually more of a timesaver if you use Verilog, where the instantiation and wires / regs don't resemble the source code like in VHDL. It's also great if you wanted to quickly make a Verilog testbench for your VHDL entity or vice versa. This goes doubly for a beginner, who may not know the basics required to start the testbench. Just my 2 cents, Gabor
From: rickman on 17 Jan 2010 15:43 On Jan 16, 10:23 pm, Gabor <ga...(a)alacron.com> wrote: > On Jan 16, 12:59 pm, KMS <kms34...(a)gmail.com> wrote: > > > Hi, > > > I recommend you change your BOOLEANs to STD_LOGIC. > > If you change the booleans to std_logic, you'll need > to change all the if statements to have a comparison > operator like > if (nickel_in) then . . . > becomes > if (nickel_in = '1') then . . . > > If you're not trying to synthesize this logic, I'm not really > clear why you shouldn't use booleans, but then I would > normally have used Verilog. I'll second that. There is nothing about Booleans that are evil. The two times I will replace a Boolean with a std_logic is when I know this is a signal that will be important in simulation or when it is at the top level of a synthesized design. I don't recall the exact issue having other than std_logic or slv at the top level, but it is not a big deal to work with that restriction. I replace a Boolean with std_logic for simulation only because a std_logic signal produces a wiggly line with levels that are easy to see while a Boolean has a state which must be read in the waveform viewer which can be difficult with small text. I like Booleans because they can be less typing when used in an IF statement or in the result of a comparison. In the end, it more a matter of preference than anything. If you like the format of your code using Booleans, go ahead. There are no real roadblocks to using them. > On the other hand, if you make the code synthesizable, > you can use the Xilinx webpack to generate a testbench > template automatically. That often saves the headache > of writing the signal declarations, instantiations and > initialization logic. I'll second that as well. But the template is only the signal declarations and the component instantiations. You still have to write the code to drive all the inputs to the UUT. Once you go a couple of simple test benches you will see how easy they are. When you need to test more complex code, you will find that your test bench needs to get a little more complex, but the same concepts apply. The main thing is to keep it simple and look at other coder's test benches to get ideas. There are a lot of good designers out there and it is always good to learn what you can from them. But don't be afraid to think for yourself too. Rick
|
Next
|
Last
Pages: 1 2 3 Prev: CPLD programming sequence XC9500 Next: Which WebPack for old Spartan and Spartan-2? |