I am attempting to design a DPIM modulator and demodulator. Essentially, what the code is supposed to do is take 4 bit data, send zeros equal to the number in data and then a single one and repeat. Thus, my data is encoded in the number of zeros. I have used a counter for the purpose but whenever i attempt to reset this counter using
if counter = data then
counter <=(others=>'0');
It doesn't work and the counter appears to reset to zero and remain there. Here is my code:
architecture Behavioral of PIM_MOD is
signal counter: std_logic_vector(0 to 3) :="0000";
signal prescaler: std_logic_vector(22 downto 0);
begin
process(clk,counter,data,reset)
begin
if rising_edge (clk) then
if (reset = '1') then
counter <= (others => '0');
prescaler <= (others => '0');
else
if prescaler < "10000000100101101000000" then
prescaler <= prescaler+1;
else
prescaler <= (others => '0');
counter <= counter+1;
end if;
end if;
end if;
if counter = data then
e <= '1';
else
e <= '0';
end if;
end process;
-
\$\begingroup\$ Where do you reset the counter to zero except in the if (reset = '1') section? Write a test bench and look at your signals in the waveform of a simulator. I’d also advise you to use std_ulogic instead of std_logic, split your processes into clocked processes (only sensitive to clk and potentially an async reset) and combinatorial processes (sensitive to all signals, in VHDL2008 you can even write process(all)) and use the unsigned type for the counters for easier arithmetic. The binary number for the prescaler is also very non-human-readable and should be defined as a constant somewhere. \$\endgroup\$Michael– Michael2020年01月16日 10:33:00 +00:00Commented Jan 16, 2020 at 10:33
-
\$\begingroup\$ i have not put it here in the code but i tried to do it after the last conditional statement using a seperate if statement.... tried to put it immediately after e<=1; inside the last if.... also tried it inside the clk if statement and outside it. It doesn't seem to make any difference and my counter simply does not reset when its value reaches data. can you suggest where to put the reset to achieve the intended goal of the circuit which is. make e<=1 when counter = data and then reset counter to start counting again. \$\endgroup\$Faisal Khaskheli– Faisal Khaskheli2020年01月16日 13:22:11 +00:00Commented Jan 16, 2020 at 13:22
1 Answer 1
It's all about where you put that code. Since it seems that you only want counter
to change when prescaler
wraps around, you need to do it within that logic, as shown here:
architecture Behavioral of PIM_MOD is
signal counter: std_logic_vector(0 to 3) :="0000";
signal prescaler: std_logic_vector(22 downto 0);
begin
process(clk,counter,data,reset)
begin
if rising_edge (clk) then
if (reset = '1') then
counter <= (others => '0');
prescaler <= (others => '0');
else
if prescaler < "10000000100101101000000" then
prescaler <= prescaler+1;
else
prescaler <= (others => '0');
if counter = data then --
counter <= (others => '0'); --
else --
counter <= counter+1; --
end if; --
end if;
end if;
end if;
if counter = data then
e <= '1';
else
e <= '0';
end if;
end process;
end Behavioral;
-
\$\begingroup\$ yeah i am using prescaler as a clock divider here to slow down the process. hmmm interesting... I will try it and get back to you. thank you very much for your response \$\endgroup\$Faisal Khaskheli– Faisal Khaskheli2020年01月16日 14:14:52 +00:00Commented Jan 16, 2020 at 14:14