The code below implements a Delta-sigma DAC in Verilog, from a Xilinx application note and I want to write equivalent VHDL code. I don't know anything about Verilog and I'm beginner in VHDL so I had to make a lot of guesses and probably beginner errors (code below). I'm not sure the translation is correct can someone help please?
Original Verilog
`timescale 100 ps / 10 ps
`define MSBI 7
module dac(DACout, DACin, Clk, Reset);
output DACout;
reg DACout;
input [`MSBI:0] DACin;
input Clk;
input Reset;
reg [`MSBI+2:0] DeltaAdder;
reg [`MSBI+2:0] SigmaAdder;
reg [`MSBI+2:0] SigmaLatch;
reg [`MSBI+2:0] DeltaB;
always @(SigmaLatch) DeltaB = {SigmaLatch[`MSBI+2], SigmaLatch[`MSBI+2]} << (`MSBI+1);
always @(DACin or DeltaB) DeltaAdder = DACin + DeltaB;
always @(DeltaAdder or SigmaLatch) SigmaAdder = DeltaAdder + SigmaLatch;
always @(posedge Clk or posedge Reset)
begin
if(Reset)
begin
SigmaLatch <= #1 1'bl << (`MSBI+1);
DACout <= #1 1'b0;
end
else
begin
SigmaLatch <== #1 SigmaAdder;
DACout <= #1 SigmaLatch[`MSBI+2];
end
end
endmodule
My try in VHDL:
entity audio is
generic(
width : integer := 8
);
port(
reset : in std_logic;
clock : in std_logic;
dacin : in std_logic_vector(width-1 downto 0);
dacout : out std_logic
);
end entity;
architecture behavioral of audio is
signal deltaadder : std_logic_vector(width+2 downto 0);
signal sigmaadder : std_logic_vector(width+2 downto 0);
signal sigmalatch : std_logic_vector(width+2 downto 0);
signal deltafeedback : std_logic_vector(width+2 downto 0);
begin
deltafeedback <= (sigmalatch(width+2), sigmalatch(width+2), others => '0');
deltaadder <= dacin + deltafeedback;
sigmaadder <= deltaadder + sigmalatch;
process(clock, reset)
begin
if (reset = '1') then
sigmalatch <= ('1', others => '0');
dacout <= '0';
elsif rising_edge(clock) then
sigmalatch <= sigmaadder;
dacout <= sigmalatch(width+2);
end if;
end process;
end architecture;
It looks like you're using ieee.std_logic_unsigned (or _arith) or both.
Please don't do that. Use ieee.numeric_std.all instead.
My Verilog is fairly non-existent, so I forget if Verilog defaults to signed or unsigned arithmetic... But whichever it is, make all your numerical signals into signed or unsigned types to match.
Your reset clause probably wants to read something like:
sigmalatch <= (width+1 => '1', others => '0');
and the deltafeedback update is something like:
deltafeedback(width+2 downto width+1) <= sigmalatch(width+2) & sigmalatch(width+2);
deltafeedback(width downto 0) <= (others => '0');
Finally, to match the Verilog, I think your width generic should be called MSBI and set to 7, (or change all your width+2s to width+1s to match your intention for the width generic)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With