I tried to generate simple parametrized IIR filter using MyHDL. The resulting code is as follows:
def iir(din, dout, nbits, acoeffs, bcoeffs, clk, n_rst):
del_len = max(len(acoeffs),len(bcoeffs))
del_line = [ Signal(intbv(0,min=din.min,max=din.max)) for i in range(del_len-1)]
@always(clk.posedge, n_rst.negedge)
def logic():
if n_rst==0:
for i in range(0,del_len):
del_line[i].next=0
dout.next=0
else:
dnext=intbv(0,min=-(1<<(2*nbits)),max=(1<<(2*nbits))-1)
idout=intbv(0,min=din.min,max=din.max)
for i in range(0,del_len):
if i==del_len-1:
dnext[:]=0
else:
dnext[:]=del_line[i]<<(nbits-1)
if i>0 and i<len(acoeffs):
dnext[:] = dnext - (acoeffs[i]*idout)
if i<len(bcoeffs):
dnext[:] = dnext + (bcoeffs[i]*din)
if i==0:
idout[:]=dnext>>(nbits-1)
else:
del_line[i-1].next=dnext>>(nbits-1)
dout.next=idout
return logic
I have also prepared a simple testbench and conversion routine (everything is in the attached zip file).
However I have faced the problem with passing of constant filter parameters .
After some experiments, which lead to conversion errors, I have defined them in the following way:
bmin=-(1<<nbits)
bmax=(1<<nbits)-1
acoeffs = [ Signal(intbv(int(i*(1<<nbits-1)),bmin,bmax)) for i in (1,-0.9)]
bcoeffs = [ Signal(intbv(int(i*(1<<nbits-1)),bmin,bmax)) for i in (0.1,0.1)]
This allows for ALMOST correct VHDL generation, but the values of the parameters are not passed to the resulting VHDL code:
-- File: iir.vhd
-- Generated by MyHDL 0.6
-- Date: Sun May 3 00:03:42 2009
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use std.textio.all;
use work.pck_myhdl_06.all;
entity iir is
port (
din: in signed (19 downto 0);
dout: out signed (19 downto 0);
clk: in std_logic;
n_rst: in std_logic
);
end entity iir;
architecture MyHDL of iir is
type t_array_acoeffs is array(0 to 2-1) of signed (19 downto 0);
signal acoeffs: t_array_acoeffs;
type t_array_bcoeffs is array(0 to 2-1) of signed (19 downto 0);
signal bcoeffs: t_array_bcoeffs;
type t_array_del_line is array(0 to 1-1) of signed (19 downto 0);
signal del_line: t_array_del_line;
begin
IIR_LOGIC: process (clk, n_rst) is
variable idout: signed(19 downto 0);
variable dnext: signed(38 downto 0);
begin
if (n_rst = '0') then
for i in 0 to 2-1 loop
del_line(i) <= "00000000000000000000";
end loop;
dout <= "00000000000000000000";
elsif rising_edge(clk) then
dnext := to_signed(0, 39);
idout := to_signed(0, 20);
for i in 0 to 2-1 loop
if (i = (2 - 1)) then
dnext := "000000000000000000000000000000000000000";
else
dnext := shift_left(resize(del_line(i), 39), (19 - 1));
end if;
if ((i > 0) and (i < 2)) then
dnext := resize(dnext - (acoeffs(i) * idout), 39);
end if;
if (i < 2) then
dnext := resize(dnext + (bcoeffs(i) * din), 39);
end if;
if (i = 0) then
idout := resize(shift_right(dnext, (19 - 1)), 20);
else
del_line((i - 1)) <= resize(shift_right(dnext, (19 - 1)), 20);
end if;
end loop;
dout <= idout;
end if;
end process IIR_LOGIC;
end architecture MyHDL;
Similar problem occurs, when I try to coinvert to Verilog (see iir.v in the attached zip). Please not, that it is not possible to uncomment both conversion commands at the same time - it leads to an error:
myhdl.ConversionError: Signal in multiple list is not supported: acoeffs(0)
When only one conversion is active - results are almost good.
I don't know. Is it a bug in MyHDL, or there is another correct method for passing of parameters?
ZIP archive with IIR filter in MyHDL and resulting Verilog and VHDL files. The results of simulation (simul.vcd) are also provided
I'm not sure signals should be used for parametrization. I think the basic (valid) problem that you have is how to use indexed constants in general for conversion. I don't have a good solution at this point. There are several issues, including dependencies on third-party synthesis tools capabilities. I propose to take the discussion to the mailing list/newsgroup first.
This Tracker item was closed automatically by the system. It was
previously set to a Pending status, and the original submitter
did not respond within 30 days (the time period specified by
the administrator of this Tracker).