質問

I've wrote this piece of code for a frequency divider in VHDL language and I don't understand why my frequency isn't divided when I simulate it. What I am doing wrong?

library IEEE;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_1164.all;

entity div is
  port(clk                      : in  std_logic;
       clk1, clkafisare, clkorg : out std_logic);
end entity;

architecture fct_div of div is
begin
  process(clk)
    variable c, e, g : integer   := 0;
    variable d, f, h : std_logic := '0';
  begin
    if rising_edge(clk) then
      e := e+1; c := c+1; g := g+1;
      if g = 12000000 and h = '0' then
        h := '1'; g := 0;
      elsif g = 12000000 and h = '1' then
        h := '0'; g := 0;
      end if;
      if c = 25000000 and d = '0' then
        d := '1'; c := 0;
      elsif c = 25000000 and d = '1' then
        d := '0'; c := 0;
      end if;
      if e = 100000 and f = '0' then
        f := '1'; e := 0;
      elsif e = 100000 and f = '1' then
        f := '0'; e := 0;
      end if;
    end if;
    clk1       <= d;
    clkafisare <= f;
    clkorg     <= h;
  end process;
end fct_div;
役に立ちましたか?

解決

A simulation shows that your code actually does generate divided clocks, but the large integers used in the division gives periods up to 500 ms when dividing a 100 MHz clock, so you may not have waited long enough :-)

You can see the simulation below.

enter image description here

You can indeed store process state in process variables, since that state is retained between suspensions of the process. Note that the process is not invoked between runs, like a ordinary software function, but simply suspended at the end (when having a sensitivity list), and execution is then resumed at an event at one of the signals in the sensitivity list.

Some comments to the code:

  • The assign to clk* should go inside the if rising_edge(clk), since you probably want these outputs to be from flip-flops.

  • Consider using the state in clk* instead of the d, f, and h variables, since it is almost redundant.

  • Consider making the counters with signal based on std_logic_vector, instead of the internal integer variables, since debugging is typically easier when using signals that can be shown easily in a waveform, and you have better control over the implementation. For example when debugging, you would have seen that the counters actually incremented, and thus may have understood that the divider works, but the resulting clock just have a long period.

他のヒント

Convert the variables into architecture level signals and switch from variable assignments to signal assignments.

You should also move the assignment of clk1, clkafisare, and clkorg into the first if-statement to describe edge sensitive registers. If you don't have a testbench you'll also have to write one to generate the clk signal before you can get any output.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top