Saturday, May 31, 2014

ModelSim testbench with reals and floats

Trying to program BladeRF's FPGA with VHDL

Summary

I tried to implement the suggestions I got from Brian. And I was successful!

The first VHDL-program is possibly not synthesizable, but it works in the simulator. The next program more or less proves (I think) that I understood Brian's suggestions. The last program has the same behaviour and uses a table that is generated at compiletime. So, the synthesized program only has some precompiled data in a table. And that is synthesizable.

Testbed

library ieee ;
    use ieee.std_logic_1164.all ;
    use ieee.numeric_std.all ;


-- tdatasource.vhd
-- May-2014 Kees de Groot
-- test-program for the datasource to test my DC-remover
-- this device simply tests the datasource

entity test_datasource is
    PORT ( sdata : out     signed(11 downto 0));
end;

architecture mytest of test_datasource is

COMPONENT datasource
port (
       reset  : in   std_logic;
clk    : in   std_logic;
sdata  : out  signed(11 downto 0)
      ) ;
END COMPONENT ;

SIGNAL clk   : std_logic := '1';
SIGNAL reset : std_logic := '0';
constant FS : real := 38.4e6 ; -- sample frequency

begin

dut : datasource
   PORT MAP (
   sdata => sdata,
   clk => clk,
   reset => reset );

clock : PROCESS(clk)
   begin
   clk <= not clk after (1.0/FS)/2.0 * (1 sec) ;
end PROCESS clock;

stimulus : PROCESS
   begin
   wait for 5 ns; reset  <= '1';
   wait for 4 ns; reset  <= '0';
   wait;
end PROCESS stimulus;

end mytest;

a testbed is to be used with the simulator. So, does not have to be synthesizable, but should run correctly.

First floating/real program


library ieee ;
    use ieee.std_logic_1164.all ;
    use ieee.numeric_std.all ;
    use ieee.math_real.all;

-- datasource.vhd
-- May-2014 Kees de Groot
-- test-program for my DC-remover
-- this device outputs a 2s-complement sine of 32 points

entity datasource is
port (
       reset  : in   std_logic;
       clk    : in   std_logic;
       sdata  : out  signed(11 downto 0)
      ) ;
end datasource;

architecture mydatasource of datasource is
  signal indexx: integer range 0 to 31;
  signal tmpdata: signed(11 downto 0);
begin
 calcindex: process (clk, reset)
        begin 
          if (reset='1') then 
            indexx <= 0; 
          elsif (rising_edge(clk)) then 
            if (indexx = 31) then
              indexx <= 0;
            else indexx <= indexx +1;
            end if;
          end if; 
      end process calcindex;
       myproc: process (indexx)
       begin
         tmpdata <= to_signed(600 + integer(1400.0 * SIN(2.0 * MATH_PI * real(indexx) / 32.0)), 12);
       end process myproc;

       sdata <= tmpdata;

end mydatasource;

I am afraid this program is not synthesizable, but it runs correctly.

Synthesizable floating/real program


library ieee ;
    use ieee.std_logic_1164.all ;
    use ieee.numeric_std.all ;
    use ieee.math_real.all;

-- datasource2.vhd
-- May-2014 Kees de Groot
-- test-program for my DC-remover
-- this device outputs a 2s-complement sine of 32 points

entity datasource is
port (
       reset  : in   std_logic;
       clk    : in   std_logic;
       sdata  : out  signed(11 downto 0)
      ) ;
end datasource;

architecture mydatasource of datasource is
  signal indexx: integer range 0 to 31;
  signal tmpdata: signed(11 downto 0);
  type sintab is array(0 to 31) of signed(11 downto 0);
  signal sinrom: sintab;

 begin
  genrom: for idx in 0 to 31 generate
    constant x: real := SIN(2.0 * MATH_PI * real(idx) / 32.0);
    constant xn: signed(11 downto 0) := to_signed(600 + integer(1400.0 * x), 12);
    begin
      sinrom(idx) <= xn;
    end generate;
   
 calcindex: process (clk, reset)
        begin 
          if (reset='1') then 
            indexx <= 0; 
          elsif (rising_edge(clk)) then 
            if (indexx = 31) then
              indexx <= 0;
            else indexx <= indexx +1;
            end if;
          end if; 
      end process calcindex;
     
       myproc: process (indexx)
       begin
         tmpdata <= sinrom(indexx);
       end process myproc;

       sdata <= tmpdata;

end mydatasource;

What did I do? I created a table called sinrom with 32 entries. In the process calcindex I simply increment an index for every clk-pulse and use that to get the corresponding value, a 12 bit number.

Picture of the simulation



Yes, I know I can get rid off some numbers using written constants. 

By the way I got the idea from:



One possible way is to calculate the table in VHDL at compile time, as shown in the below example. (It's a 0..pi sine table, not the solution for your problem).

Code:
TYPE SINTAB IS ARRAY(0 TO ROMSIZE-1) OF STD_LOGIC_VECTOR (NNCO-2 DOWNTO 0);
SIGNAL SINROM: SINTAB;

BEGIN

GENROM:
FOR idx in 0 TO ROMSIZE-1 GENERATE
         CONSTANT x: REAL := SIN(real(idx)*MATH_PI/real(ROMSIZE));
         CONSTANT xn: UNSIGNED (NNCO-2 DOWNTO 0) := CONV_UNSIGNED(INTEGER(x*real(ROMMAX)),NNCO-1);
BEGIN
         SINROM(idx) <= STD_LOGIC_VECTOR(xn);       
END GENE



Saturday, May 3, 2014

ModelSim testbench is the perfect companion for BladeRF VHDL-development

ModelSim is awesome indeed!

I took the plunge and did the Altera tutorial that came with ModelSim. Look in the help-files of ModelSim and you'll find the tutorial.

Summary

I found a lot of ModelSim tutorials on the web, all for a different version of ModelSim. Then I decided to invest in reading/studying/doing the Altera-tutorial from the help-file of ModelSim. After one Sunday-afternoon I had the tutorial running. What a satisfaction! 
I often write down all the steps I perform in a Word-document, my electronic diary. I simply use <Ctrl><Alt><PrtScr> and paste the screenshots in my Word-diary.
Because the bladeRF LMS-source is too difficult to simulate for the moment, I am a newby in ModelSim, I decided to design in VHDL a simple datasource for a sine with a DC-offset. Later I will test my DC-remover on this datasource.

I was too lazy to type in 32 12-bit values in the case-statement, so used a python-program to do this.

I managed to write and debug the code using ModelSim. 
The whole struggle with ModelSim is in here but you might be wise and skip to the end for the final result.
I finally constructed the datasource.vhd and the testbench tdatasource.vhd

ModelSim Tutorials on the web:

1.       http://www.stanford.edu/class/ee183/handouts_win2003/Modelsim_short_tutorial.pdf
Stanford, Winter 2002-2003, Modelsim SE (Student Edition?), 14 pages
Tutorial with Verilog only
2.       http://bertrand.granado.free.fr/Sysprog/SysProg/Cours_files/modelsim_tut.pdf
Mentor Graphics Corporation, 2009, Software Version 6.5b, 82 pages
3.       ftp://ftp.altera.com/up/pub/Altera_Material/10.1/Tutorials/Using_ModelSim.pdf
Altera, Jan 2011, Altera Starter Edition 6.4.a Custom Altera Version, 30 pages
4.       http://www.ece.northwestern.edu/~ismail/courses/c92/ModelSim_Tutorial.pdf
Larbi Boughaleb, UT ECE,  ModelSim 5.7, 9 pages
7.       Mentor Graphics, 2008, Software Version 6.4a, 88 pages
8.       http://users.ece.cmu.edu/~kbiswas/modelsim/se_tutor.pdf
Mentor Graphics Corporation, Nov 2004, Version 6.0b, 178 pages
9.       modelsim_tut.pdf from help-file Modelsim 10.1d
Mentor Graphics Corporation, 2012, Version 10.1d, 80 pages
The last one, number 9, is from the help-file of the current ModelSim on my laptop.


Which version of ModelSim do I have?
ModelSim-Altera 10.1d (Quartus II 13.1)

ModelSim tutorial

I took the plunge and folowed the tutorial from the help-file in ModelSim, described above as #9.
It took me only one Sunday-afternoon and I had the counter-example running. The remaining evening was used to play with ModelSim. Awesome!
So, read the tutorial, take your time, and just try. This investment is worth your time!

Test-source for my DC-remover

Fort testing my DC-remover I need a simple source that I can simulate with ModelSim.
I want to construct a simple source that delivers a sinus with an offset.
My source has a 12-bit 2s-complement output. The average output will be 600.
12 bit is 4096 max, so +/- 2048. Let’s make my sinus 600 + 1400*sin(wt), so the outout-value will be 600-1400= -800 … 600+1400=2000.
The output will be -800…2000.
If my DC-remover is OK, the final output will be +/- 1400, so the original sine with DC-offset removed.

Port specification:

entity datasource is
port (
     reset : in std_logic;
clk  : in std_logic;
sdata : out signed(11 downto 0)
      ) ;
end entity;

samplerate is 4 MHz. I want 32 samples/period. So my sine has a frequency of 4/32 MHz = 125 kHz.

I need an internal 5 bits counter. This counter is reset by the signal reset and increments with every clk-pulse.
The 5-bits output of this counter selects a number from a table. Perhaps a case statement.

The code-fragment for the counter:

  signal index: std_logic_vector(4 downto 0);
      process (clk, reset)
        begin 
          if (reset='1') then 
            tmp <= "00000"; 
          elsif (rising_edge(clk)) then 
            index <= index + 1;
          end if; 
      end process;

And the case=statement to calculate the 12-bit output:

signal tmpdata: std_logic_vector(11 downto 0);
     myproc: process (index)
     begin
          case(index) is
          when “00000” => tmpdata <= “000000000000”;
          when “00001” => tmpdata <= “000000111111”;
          ….
          when “11110” => tmpdata <= “111111100000”;
          when “11111” => tmpdata <= “111111111000”;
          when others => tmpdata ,= “000000000000”;
          end case;
     end process my_proc;

     sdata <= tmpdata;

The right values for the right-side of the when can be calculated with a simple python-program

(and I must admit I did not study the tobin-code, but it works (me coward!))

# GenVHDLsin01.py
# Apr-2014 Kees de Groot
#
# generate VHDL when statements for sine-wave

import pylab as pl
import numpy as np
from math import sin, cos, pi

n = 32

def tobin(x, count=8):
        """
        Integer to binary
        Count is number of bits
        """
        return "".join(map(lambda y:str((x>>y)&1), range(count-1, -1, -1)))

for i in range(n):
    data = sin(2 * pi * i / n)
    output = 600 + 1400 * data
    intout = int(output)
    #print i, data, output, intout, bin(intout), tobin(intout,12)
    print "when", '"'+ tobin(i,5)+'"'," => tmpdata <= ", '"' + tobin(intout,12) + '"'


which outputs:

when "00000"  => tmpdata <=  "001001011000"
when "00001"  => tmpdata <=  "001101101001"
when "00010"  => tmpdata <=  "010001101111"
when "00011"  => tmpdata <=  "010101100001"
when "00100"  => tmpdata <=  "011000110101"
when "00101"  => tmpdata <=  "011011100100"
when "00110"  => tmpdata <=  "011101100101"
when "00111"  => tmpdata <=  "011110110101"
when "01000"  => tmpdata <=  "011111010000"
when "01001"  => tmpdata <=  "011110110101"
when "01010"  => tmpdata <=  "011101100101"
when "01011"  => tmpdata <=  "011011100100"
when "01100"  => tmpdata <=  "011000110101"
when "01101"  => tmpdata <=  "010101100001"
when "01110"  => tmpdata <=  "010001101111"
when "01111"  => tmpdata <=  "001101101001"
when "10000"  => tmpdata <=  "001001011000"
when "10001"  => tmpdata <=  "000101000110"
when "10010"  => tmpdata <=  "000001000000"
when "10011"  => tmpdata <=  "111101001111"
when "10100"  => tmpdata <=  "111001111011"
when "10101"  => tmpdata <=  "110111001100"
when "10110"  => tmpdata <=  "110101001011"
when "10111"  => tmpdata <=  "110011111011"
when "11000"  => tmpdata <=  "110011100000"
when "11001"  => tmpdata <=  "110011111011"
when "11010"  => tmpdata <=  "110101001011"
when "11011"  => tmpdata <=  "110111001100"
when "11100"  => tmpdata <=  "111001111011"
when "11101"  => tmpdata <=  "111101001111"
when "11110"  => tmpdata <=  "000001000000"
when "11111"  => tmpdata <=  "000101000110"

So, the case=statement to calculate the 12-bit output:

signal tmpdata: std_logic_vector(11 downto 0);
     myproc: process (index)
     begin
          case(index) is
when "00000"  => tmpdata <=  "001001011000"
when "00001"  => tmpdata <=  "001101101001"
when "00010"  => tmpdata <=  "010001101111"
when "00011"  => tmpdata <=  "010101100001"
when "00100"  => tmpdata <=  "011000110101"
when "00101"  => tmpdata <=  "011011100100"
when "00110"  => tmpdata <=  "011101100101"
when "00111"  => tmpdata <=  "011110110101"
when "01000"  => tmpdata <=  "011111010000"
when "01001"  => tmpdata <=  "011110110101"
when "01010"  => tmpdata <=  "011101100101"
when "01011"  => tmpdata <=  "011011100100"
when "01100"  => tmpdata <=  "011000110101"
when "01101"  => tmpdata <=  "010101100001"
when "01110"  => tmpdata <=  "010001101111"
when "01111"  => tmpdata <=  "001101101001"
when "10000"  => tmpdata <=  "001001011000"
when "10001"  => tmpdata <=  "000101000110"
when "10010"  => tmpdata <=  "000001000000"
when "10011"  => tmpdata <=  "111101001111"
when "10100"  => tmpdata <=  "111001111011"
when "10101"  => tmpdata <=  "110111001100"
when "10110"  => tmpdata <=  "110101001011"
when "10111"  => tmpdata <=  "110011111011"
when "11000"  => tmpdata <=  "110011100000"
when "11001"  => tmpdata <=  "110011111011"
when "11010"  => tmpdata <=  "110101001011"
when "11011"  => tmpdata <=  "110111001100"
when "11100"  => tmpdata <=  "111001111011"
when "11101"  => tmpdata <=  "111101001111"
when "11110"  => tmpdata <=  "000001000000"
when "11111"  => tmpdata <=  "000101000110"
          when others => tmpdata <= “000000000000”;
          end case;
     end process my_proc;

     sdata <= tmpdata;

Now collect all fragments and produce the VHDL-program datasource.vhd

Note that I forgot the semicolons, not too much editing adding 32 semicolons...

-- datasource.vhd
-- May-2014 Kees de Groot
-- test-program for my DC-remover
-- this device outputs a 2s-complement sine of 32 points

entity datasource is
port (
       reset  : in   std_logic;
clk    : in   std_logic;
sdata  : out  signed(11 downto 0)
      ) ;
end;

architecture mydatasource of datasource is
begin
  signal index: std_logic_vector(4 downto 0);
 calcindex:     process (clk, reset)
        begin 
          if (reset='1') then 
            tmp <= "00000"; 
          elsif (rising_edge(clk)) then 
            index <= index + 1;
          end if; 
      end process calcindex;
signal tmpdata: std_logic_vector(11 downto 0);
       myproc: process (index)
       begin
             case(index) is
when "00000"  => tmpdata <=  "001001011000";
when "00001"  => tmpdata <=  "001101101001";
when "00010"  => tmpdata <=  "010001101111";
when "00011"  => tmpdata <=  "010101100001";
when "00100"  => tmpdata <=  "011000110101";
when "00101"  => tmpdata <=  "011011100100";
when "00110"  => tmpdata <=  "011101100101";
when "00111"  => tmpdata <=  "011110110101";
when "01000"  => tmpdata <=  "011111010000";
when "01001"  => tmpdata <=  "011110110101";
when "01010"  => tmpdata <=  "011101100101";
when "01011"  => tmpdata <=  "011011100100";
when "01100"  => tmpdata <=  "011000110101";
when "01101"  => tmpdata <=  "010101100001";
when "01110"  => tmpdata <=  "010001101111";
when "01111"  => tmpdata <=  "001101101001";
when "10000"  => tmpdata <=  "001001011000";
when "10001"  => tmpdata <=  "000101000110";
when "10010"  => tmpdata <=  "000001000000";
when "10011"  => tmpdata <=  "111101001111";
when "10100"  => tmpdata <=  "111001111011";
when "10101"  => tmpdata <=  "110111001100";
when "10110"  => tmpdata <=  "110101001011";
when "10111"  => tmpdata <=  "110011111011";
when "11000"  => tmpdata <=  "110011100000";
when "11001"  => tmpdata <=  "110011111011";
when "11010"  => tmpdata <=  "110101001011";
when "11011"  => tmpdata <=  "110111001100";
when "11100"  => tmpdata <=  "111001111011";
when "11101"  => tmpdata <=  "111101001111";
when "11110"  => tmpdata <=  "000001000000";
when "11111"  => tmpdata <=  "000101000110";
             when others => tmpdata <= “000000000000”;
             end case;
       end process my_proc;

       sdata <= tmpdata;

end mydatasource;


I need a testbed, the VHDL-program tdatasource.vhd

-- tdatasource.vhd
-- May-2014 Kees de Groot
-- test-program for the datasource to test my DC-remover
-- this device simply tests the datasource

entity test_datasource is
    PORT ( sourceout : out signed(11 downto 0);
end;

architecture mytest of test_datasourece is

COMPONENT datasource
port (
       reset  : in   std_logic;
clk    : in   std_logic;
sdata  : out  signed(11 downto 0)
      ) ;
END COMPONENT ;

SIGNAL clk   : bit := '0';
SIGNAL reset : bit := '0';

begin

dut : datasource
   PORT MAP (
   sdata => sdata,
   clk => clk,
   reset => reset );

clock : PROCESS
   begin
   wait for 10 ns; clk  <= not clk;
end PROCESS clock;

stimulus : PROCESS
   begin
   wait for 5 ns; reset  <= '1';
   wait for 4 ns; reset  <= '0';
   wait;
end PROCESS stimulus;

end only;

I copy these two files datasource.vhd and tdatasource.vhd to C:\altera\work
Then start ModelSim, point to this directory, compile, start simulation and run

I start NotePad, paste the above source in NotePad, then save it to C:\altera\work\datasource.vhd
The same for tdatasource.vhd

Now I should have both files in C:\altera\work:



The other files from the tutorial are still there but that does not harm hopefully…


Now start ModelSim and point to that directory



Simply close this screen

Oops, it starts the last project,
So File > New Project



click on Add existing File



Browse and add datasource and tdatasource





click Create Simulation



Cancel

Simulate  > start simulation

Cancel

I have to compile first!

Compile > compile all

# Compile of tdatasource.vhd failed with 2 errors.
# 2 compiles, 2 failed with 6 errors.

Of course, 1st time!


I did not specify any library, I thought that was not necessary for a simulation: stupid!

doubleclick on t\datasource.vhd in the project menu at the left opens the source in WordPad.
I have to add libraries: which? IEEE…??
 Parenthesis missing
Correct  to

    PORT ( sourceout : out     signed(11 downto 0));

Save and compile again


Same error

I still think it is a library problem

I’ll have a look in the LMS-bladerf file and copy the IEE lib spec

Add

library ieee ;
    use ieee.std_logic_1164.all ;
    use ieee.numeric_std.all ;

to the start of both vhd-files

Save and compile again



Typo datasourece, should be datasource

Now I see:

# 2 compiles, 2 failed with 42 errors.
# Compile of datasource.vhd failed with 40 errors.
# Compile of tdatasource.vhd failed with 2 errors.
# 2 compiles, 2 failed with 42 errors.




library ieee ;
    use ieee.std_logic_1164.all ;
    use ieee.numeric_std.all ;


-- tdatasource.vhd
-- May-2014 Kees de Groot
-- test-program for the datasource to test my DC-remover
-- this device simply tests the datasource

entity test_datasource is
    PORT ( sdata : out     signed(11 downto 0));
end;

architecture mytest of test_datasource is

COMPONENT datasource
port (
       reset  : in   std_logic;
clk    : in   std_logic;
sdata  : out  signed(11 downto 0)
      ) ;
END COMPONENT ;

SIGNAL clk   : std_logic := '0';
SIGNAL reset : std_logic := '0';

begin

dut : datasource
   PORT MAP (
   sdata => sdata,
   clk => clk,
   reset => reset );

clock : PROCESS
   begin
   wait for 10 ns; clk  <= not clk;
end PROCESS clock;

stimulus : PROCESS
   begin
   wait for 5 ns; reset  <= '1';
   wait for 4 ns; reset  <= '0';
   wait;
end PROCESS stimulus;

end mytest;

tdatasource.vhd is now succesfull compiled!

Now concentrate on datasource.vhd

Doubleclick in the lower window on the red error-message opens a window with the errormessages

Double click on the file datasource.vhd to open it in the editor

After some corrections the source compiles without errors:

library ieee ;
    use ieee.std_logic_1164.all ;
    use ieee.numeric_std.all ;

-- datasource.vhd
-- May-2014 Kees de Groot
-- test-program for my DC-remover
-- this device outputs a 2s-complement sine of 32 points

entity datasource is
port (
       reset  : in   std_logic;
       clk    : in   std_logic;
       sdata  : out  signed(11 downto 0)
      ) ;
end datasource;

architecture mydatasource of datasource is
  signal tmpdata: signed(11 downto 0);
begin
 cal  signal indexx: signed(4 downto 0);
cindex: process (clk, reset)
        begin 
          if (reset='1') then 
            tmpdata <= "000000000000"; 
          elsif (rising_edge(clk)) then 
            indexx <= indexx + 1;
          end if; 
      end process calcindex;
       myproc: process (indexx)
       begin
             case(indexx) is
when "00000"  => tmpdata <=  "001001011000";
when "00001"  => tmpdata <=  "001101101001";
when "00010"  => tmpdata <=  "010001101111";
when "00011"  => tmpdata <=  "010101100001";
when "00100"  => tmpdata <=  "011000110101";
when "00101"  => tmpdata <=  "011011100100";
when "00110"  => tmpdata <=  "011101100101";
when "00111"  => tmpdata <=  "011110110101";
when "01000"  => tmpdata <=  "011111010000";
when "01001"  => tmpdata <=  "011110110101";
when "01010"  => tmpdata <=  "011101100101";
when "01011"  => tmpdata <=  "011011100100";
when "01100"  => tmpdata <=  "011000110101";
when "01101"  => tmpdata <=  "010101100001";
when "01110"  => tmpdata <=  "010001101111";
when "01111"  => tmpdata <=  "001101101001";
when "10000"  => tmpdata <=  "001001011000";
when "10001"  => tmpdata <=  "000101000110";
when "10010"  => tmpdata <=  "000001000000";
when "10011"  => tmpdata <=  "111101001111";
when "10100"  => tmpdata <=  "111001111011";
when "10101"  => tmpdata <=  "110111001100";
when "10110"  => tmpdata <=  "110101001011";
when "10111"  => tmpdata <=  "110011111011";
when "11000"  => tmpdata <=  "110011100000";
when "11001"  => tmpdata <=  "110011111011";
when "11010"  => tmpdata <=  "110101001011";
when "11011"  => tmpdata <=  "110111001100";
when "11100"  => tmpdata <=  "111001111011";
when "11101"  => tmpdata <=  "111101001111";
when "11110"  => tmpdata <=  "000001000000";
when "11111"  => tmpdata <=  "000101000110";
when others => tmpdata <= "000000000000";
             end case;
       end process myproc;

       sdata <= tmpdata;

end mydatasource;

Simulate > start simulation


Quite encouraging:



Right click on the objects windows and “add wave”

Click on run

Lower left type “run 500 ns”



Well, not any output still…

It looks like indexx is never initialized, so remains at “XXXXX”

Change

          if (reset='1') then 
            tmpdata <= "000000000000";
            index <= "00000"; 
          elsif (rising_edge(clk)) then 

end simulation
save, compile, simulate, run




It looks like some signals are not defined yet!

I get XXX in the wave-display.

Why? Exactly what Brian explained: define signals in one process, at one place only. No multiple assignments! If there more sources, one source tells "it is a ONE!" and another source yells "it is a ZERO" then what shouyld be the outcome??

I changed my source and now it is ok. ModelSim is awesome indeed!!!

I tested my datasource.vhd and now I can finally test my dcremover.vhd in the same way.


Here is the final source of datasource.vhd

Note that I renamed index to indexx because index might be a reserved word perhaps?

library ieee ;
    use ieee.std_logic_1164.all ;
    use ieee.numeric_std.all ;

-- datasource.vhd
-- May-2014 Kees de Groot
-- test-program for my DC-remover
-- this device outputs a 2s-complement sine of 32 points

entity datasource is
port (
       reset  : in   std_logic;
       clk    : in   std_logic;
       sdata  : out  signed(11 downto 0)
      ) ;
end datasource;

architecture mydatasource of datasource is
  signal indexx: signed(4 downto 0);
  signal tmpdata: signed(11 downto 0);
begin
 calcindex: process (clk, reset)
        begin 
          if (reset='1') then 
            indexx <= "00000"; 
          elsif (rising_edge(clk)) then 
            indexx <= indexx + 1;
          end if; 
      end process calcindex;
       myproc: process (indexx)
       begin
             case(indexx) is
when "00000"  => tmpdata <=  "001001011000";
when "00001"  => tmpdata <=  "001101101001";
when "00010"  => tmpdata <=  "010001101111";
when "00011"  => tmpdata <=  "010101100001";
when "00100"  => tmpdata <=  "011000110101";
when "00101"  => tmpdata <=  "011011100100";
when "00110"  => tmpdata <=  "011101100101";
when "00111"  => tmpdata <=  "011110110101";
when "01000"  => tmpdata <=  "011111010000";
when "01001"  => tmpdata <=  "011110110101";
when "01010"  => tmpdata <=  "011101100101";
when "01011"  => tmpdata <=  "011011100100";
when "01100"  => tmpdata <=  "011000110101";
when "01101"  => tmpdata <=  "010101100001";
when "01110"  => tmpdata <=  "010001101111";
when "01111"  => tmpdata <=  "001101101001";
when "10000"  => tmpdata <=  "001001011000";
when "10001"  => tmpdata <=  "000101000110";
when "10010"  => tmpdata <=  "000001000000";
when "10011"  => tmpdata <=  "111101001111";
when "10100"  => tmpdata <=  "111001111011";
when "10101"  => tmpdata <=  "110111001100";
when "10110"  => tmpdata <=  "110101001011";
when "10111"  => tmpdata <=  "110011111011";
when "11000"  => tmpdata <=  "110011100000";
when "11001"  => tmpdata <=  "110011111011";
when "11010"  => tmpdata <=  "110101001011";
when "11011"  => tmpdata <=  "110111001100";
when "11100"  => tmpdata <=  "111001111011";
when "11101"  => tmpdata <=  "111101001111";
when "11110"  => tmpdata <=  "000001000000";
when "11111"  => tmpdata <=  "000101000110";
when others => tmpdata <= "000000000000";
             end case;
       end process myproc;

       sdata <= tmpdata;

end mydatasource;

Somehow I found this URL on the web:


Analogue Waveforms

Modelsim can display a signal in your VHDL/Verilog design as an analogue signal. One use for this is when you want to visualise the output of a digital to analogue converter to see if you have synthesised the waveform as you intended. To do this you can right-click on the signal name in the Wave window and select it's properties. Switch to the Format tab and select 'Analogue'. You can optionally set a maximum value for the signal so that Modelsim can stretch your waveform to fit the height of the row. For example, set it to 255 for an 8-bit DAC value.






 It is even possible to get a decimal value of the wave under the cursor!!

Epilogue

Yes, ModelSim is awesome indeed. Testbenches are not difficult to construct once you grasp the overall idea. Now I am gonna make a testbench for my DC-remover using the above datasource.

Don't be afraid/shy study Altera's tutorial!