Myhdl code

Designing Hardware (for e.g. FPGAs) in python.
The follwing is a small example which shows a hardware description which is able to generate a sinus waveform using the recursive chebycheff formulation.

### Explanation:
# Myhdl (wwww.myhdl.org) is a python package which allows you to describe 
# Hardware code (i.e. for an fpga) in python. This code can then be convert # to (VHDL or Verilog). For me the best thing about the idea is that you can # write the Testbench also in python. This allows to create complex high # level Test behavior easily. Python has many high level packages to # accomplish this. (Of curse the high level Testbench cannot be converted # to vhdl or verilog. In fact only a synthesis-able subset can). The # downside is that it is still in development. But a hole bunch of very # usefull stuff is allready working. A example of a 
# continous Wave sinus Generator: 

from myhdl import *
from math import cos,pi
import pylab
def unit_singen(i_clk,i_reset,i_enable,o_outvalue,frequenzSIN,clkfrequnez):
    INTERNALWIDTH=len(o_outvalue)-2  #
    #OUT_MAX_POSSIBLE=o_outvalue.max
    #OUT_MIN_POSSIBLE=o_outvalue.min
    KONSTANT_FACTOR=int(cos(2*pi*frequenzSIN*1.0/clkfrequnez)*2**(INTERNALWIDTH))

    Reg_T0=Signal(intbv((2**(INTERNALWIDTH))-1,min=o_outvalue.min,max=o_outvalue.max))
    Reg_T1=Signal(intbv(KONSTANT_FACTOR,min=o_outvalue.min,max=o_outvalue.max))

    @always(i_clk.posedge,i_reset.negedge)
    def logicCC():
      if i_reset== 0 :
	Reg_T0.next=(2**(INTERNALWIDTH))-1
	Reg_T1.next=KONSTANT_FACTOR
      else:
	if i_enable==1:
	  Reg_T0.next=Reg_T1
	  Reg_T1.next=((KONSTANT_FACTOR * Reg_T1)>>(INTERNALWIDTH-1)) - Reg_T0

    @always_comb
    def comb_logic():
      o_outvalue.next=Reg_T1

    return instances()

def test_singen(SimulateNPoints=200):
   OUTPUT_BITWIDTH=50
   Sinusvalue=Signal(intbv(0,min=-2**OUTPUT_BITWIDTH,max=2**OUTPUT_BITWIDTH))
   clk=Signal(bool(0))
   enable=Signal(bool(0))
   reset=Signal(bool(0))
   frequenzSIN=0.5e6   # make a 3.00 mhz Sinus
   clk_frequnez=10e6 # 10 mhz 
   clk_period=1.0/clk_frequnez
   singen_inst = unit_singen(clk,reset,enable,Sinusvalue,frequenzSIN,clk_frequnez)

   @always(delay(int(clk_period*0.5*1e9)))  ## delay in nano sekonds
   def clkgen():
       clk.next = not clk

   sinlist=[]
   @instance
   def stimulus():
       while 1:
	 reset.next=0
	 enable.next=0
	 yield clk.posedge
	 reset.next=1
	 yield clk.posedge
	 enable.next=1
	 for i in range(SimulateNPoints):
	    yield clk.posedge
	    #yield delay(10)
	    sinlist.append(int(Sinusvalue))
	    print Sinusvalue

	 pylab.figure(1)
	 pylab.subplot(211)
	 #print len(pylab.arange(0.0,clk_period*(len(sinlist)-0.5),clk_period)), len(sinlist)
	 pylab.plot(pylab.arange(0.0,clk_period*(len(sinlist)-0.5),clk_period),sinlist)
	 pylab.xlabel("Time")
	 pylab.ylabel("Amplitude")
	 pylab.subplot(212)
	 pylab.semilogy(pylab.arange(-clk_frequnez/2.0,clk_frequnez/2.0,clk_frequnez/(len(sinlist))),abs(pylab.fftshift(pylab.fft(pylab.array(sinlist)))))
	 pylab.xlabel("Frequenz")
	 pylab.ylabel("Amplitude")
	 pylab.show()
	 raise StopSimulation

   toVHDL(unit_singen,clk,reset,enable,Sinusvalue,frequenzSIN,clk_frequnez)

   return instances()

    #

if __name__ == '__main__':
    sim = Simulation(test_singen(SimulateNPoints=200))
    sim.run()

    #singen_inst = unit_singen(Outvalue,clk,enable,reset,frequenz=20)

    #toVHDL(unit_singen,clk,reset,enable,Outvalue,frequenz)
    #simulate(2000) 

The Frequency plot of the Sin-Waveform-Generator
(Can you do this so short and nice with conventional vhdl or verilog tools ??):

  

The Generated VHDL Code:

-- File: unit_singen.vhd
-- Generated by MyHDL 0.7
-- Date: Tue Jan 10 12:49:59 2012

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use std.textio.all;

use work.pck_myhdl_07.all;

entity unit_singen is
    port (
        i_clk: in std_logic;
        i_reset: in std_logic;
        i_enable: in std_logic;
        o_outvalue: out signed (50 downto 0)
    );
end entity unit_singen;

architecture MyHDL of unit_singen is

signal Reg_T1: signed (50 downto 0);
signal Reg_T0: signed (50 downto 0);

begin

o_outvalue <= Reg_T1;

UNIT_SINGEN_LOGICCC: process (i_clk, i_reset) is
begin
    if (i_reset = '0') then
        Reg_T0 <= to_signed((2 ** 49) - 1, 51);
        Reg_T1 <= "001111001101111000011100001001101000100010101001111";
    elsif rising_edge(i_clk) then
        if (i_enable = '1') then
            Reg_T0 <= Reg_T1;
            Reg_T1 <= resize(shift_right((535397221549391 * Reg_T1), (49 - 1)) - Reg_T0, 51);
        end if;
    end if;
end process UNIT_SINGEN_LOGICCC;

end architecture MyHDL;
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: