2 hanke998 hanke998 于 2014.09.23 17:55 提问

帮忙把VHDL主程序转化成verilog语言的。。。跪谢啊

entity dac3283_ctrl is
generic (
START_ADDR : std_logic_vector(27 downto 0) := x"0000000";
STOP_ADDR : std_logic_vector(27 downto 0) := x"00000FF"
);
port (
rst : in std_logic;
clk : in std_logic;
-- Sequence interface
init_ena : in std_logic;
init_done : out std_logic;
-- Command Interface
clk_cmd : in std_logic;
in_cmd_val : in std_logic;
in_cmd : in std_logic_vector(63 downto 0);
out_cmd_val : out std_logic;
out_cmd : out std_logic_vector(63 downto 0);
in_cmd_busy : out std_logic;
-- SPI control
spi_n_oe : out std_logic;
spi_n_cs : out std_logic;
spi_sclk : out std_logic;
spi_sdo : out std_logic;
spi_sdi : in std_logic
);
end dac3283_ctrl;

architecture dac3283_ctrl_syn of dac3283_ctrl is

component fmc150_stellar_cmd is
generic
(
START_ADDR : std_logic_vector(27 downto 0) := x"0000000";
STOP_ADDR : std_logic_vector(27 downto 0) := x"00000FF"
);
port
(
reset : in std_logic;
-- Command Interface
clk_cmd : in std_logic; --cmd_in and cmd_out are synchronous to this clock;
out_cmd : out std_logic_vector(63 downto 0);
out_cmd_val : out std_logic;
in_cmd : in std_logic_vector(63 downto 0);
in_cmd_val : in std_logic;
-- Register interface
clk_reg : in std_logic; --register interface is synchronous to this clock
out_reg : out std_logic_vector(31 downto 0); --caries the out register data
out_reg_val : out std_logic; --the out_reg has valid data (pulse)
out_reg_addr : out std_logic_vector(27 downto 0); --out register address
in_reg : in std_logic_vector(31 downto 0); --requested register data is placed on this bus
in_reg_val : in std_logic; --pulse to indicate requested register is valid
in_reg_req : out std_logic; --pulse to request data
in_reg_addr : out std_logic_vector(27 downto 0); --requested address
--mailbox interface
mbx_in_reg : in std_logic_vector(31 downto 0); --value of the mailbox to send
mbx_in_val : in std_logic --pulse to indicate mailbox is valid
);
end component fmc150_stellar_cmd;

component pulse2pulse
port (
rst : in std_logic;
in_clk : in std_logic;
out_clk : in std_logic;
pulsein : in std_logic;
pulseout : out std_logic;
inbusy : out std_logic
);
end component;

component dac3283_init_mem is
port (
clka : in std_logic;
addra : in std_logic_vector(4 downto 0);
douta : out std_logic_vector(15 downto 0)
);
end component;

constant ADDR_GLOBAL : std_logic_vector := x"0000020";
constant ADDR_MAX_WR : std_logic_vector := x"000001F";
constant ADDR_MAX_RD : std_logic_vector := x"000001F";

type sh_states is (idle, instruct, data_io, data_valid);
signal sh_state : sh_states;

signal serial_clk : std_logic;
signal sclk_ext : std_logic;

signal out_reg_val : std_logic;
signal out_reg_addr : std_logic_vector(27 downto 0);
signal out_reg : std_logic_vector(31 downto 0);

signal in_reg_req : std_logic;
signal in_reg_addr : std_logic_vector(27 downto 0);
signal in_reg_val : std_logic;
signal in_reg : std_logic_vector(31 downto 0);

signal done_sclk : std_logic;
signal init_done_sclk : std_logic;
signal init_done_tmp : std_logic;
signal init_done_prev : std_logic;

signal init : std_logic;
signal init_tmp : std_logic;
signal init_reg : std_logic;

signal inst_val : std_logic;
signal inst_reg_val : std_logic;
signal inst_rw : std_logic;
signal inst_reg : std_logic_vector(4 downto 0);
signal data_reg : std_logic_vector(7 downto 0);

signal sh_counter : integer;
signal shifting : std_logic;
signal read_n_write : std_logic;
signal ncs_int : std_logic;
signal busy : std_logic;
signal sdi : std_logic;

signal shift_reg : std_logic_vector(15 downto 0);
signal init_address : std_logic_vector(4 downto 0);
signal init_data : std_logic_vector(15 downto 0);

signal read_byte_val : std_logic;
signal data_read_val : std_logic;
signal data_read : std_logic_vector(7 downto 0);

begin


-- Generate serial clock (max 20MHz)

process (clk)
-- Divide by 2^4 = 16, CLKmax = 16 x 20MHz = 320MHz
variable clk_div : std_logic_vector(3 downto 0) := (others => '0');
begin
if (rising_edge(clk)) then
clk_div := clk_div + '1';
-- The slave samples the data on the rising edge of SCLK.
-- therefore we make sure the external clock is slightly
-- after the internal clock.
sclk_ext <= clk_div(clk_div'length-1);
serial_clk <= sclk_ext;
end if;
end process;


-- Stellar Command Interface

fmc150_stellar_cmd_inst : fmc150_stellar_cmd
generic map
(
START_ADDR => START_ADDR,
STOP_ADDR => STOP_ADDR
)
port map
(
reset => rst,

clk_cmd => clk_cmd,
in_cmd_val => in_cmd_val,
in_cmd => in_cmd,
out_cmd_val => out_cmd_val,
out_cmd => out_cmd,

clk_reg => clk,
out_reg_val => out_reg_val,
out_reg_addr => out_reg_addr,
out_reg => out_reg,

in_reg_req => in_reg_req,
in_reg_addr => in_reg_addr,
in_reg_val => in_reg_val,
in_reg => in_reg,

mbx_in_val => '0',
mbx_in_reg => (others => '0')
);


-- Shoot commands to the state machine

process (rst, clk)
begin
if (rst = '1') then

init_done      <= '0';
init_done_tmp  <= '0';
init_done_prev <= '0';
init           <= '0';
in_reg_val     <= '0';
in_reg         <= (others => '0');
inst_val       <= '0';
inst_rw        <= '0';
inst_reg       <= (others=> '0');
data_reg       <= (others=> '0');

elsif (rising_edge(clk)) then

init_done      <= init_done_sclk;

init_done_tmp  <= done_sclk;
init_done_prev <= init_done_tmp;

-- Release the init flag on rising edge init done
if (init_done_tmp = '1' and init_done_prev = '0') then
  init <= '0';
-- Enable the init flag when enable flag is high, but done flag is low
elsif (init_ena = '1' and init_done_tmp = '0') then
  init <= '1';
-- There is one additional status and control register available
elsif (out_reg_val = '1' and out_reg_addr = ADDR_GLOBAL) then
  init <= out_reg(0);
end if;

-- There is one additional status and control register available
if (in_reg_req = '1' and in_reg_addr = ADDR_GLOBAL) then
  in_reg_val <= '1';
  in_reg     <= conv_std_logic_vector(0, 27) & '0' & busy & '0' & '0' & init_done_prev;
-- read from serial if when address is within device range
elsif (in_reg_addr <= ADDR_MAX_RD) then
  in_reg_val <= data_read_val;
  in_reg     <= conv_std_logic_vector(0, 24) & data_read;
else
  in_reg_val <= '0';
  in_reg     <= in_reg;
end if;

-- Write instruction, only when address is within device range
if (out_reg_val = '1' and out_reg_addr <= ADDR_MAX_WR) then
  inst_val <= '1';
  inst_rw  <= '0'; -- write
  inst_reg <= out_reg_addr(4 downto 0);
  data_reg <= out_reg(7 downto 0);
-- Read instruction, only when address is within device range
elsif (in_reg_req = '1' and in_reg_addr <= ADDR_MAX_RD) then
  inst_val <= '1';
  inst_rw  <= '1'; -- read
  inst_reg <= in_reg_addr(4 downto 0);
  data_reg <= data_reg;
-- No instruction
else
  inst_val <= '0';
  inst_rw  <= inst_rw;
  inst_reg <= inst_reg;
  data_reg <= data_reg;
end if;

end if;
end process;

-- Intruction pulse
pulse2pulse_inst0 : pulse2pulse
port map
(
rst => rst,
in_clk => clk,
out_clk => serial_clk,
pulsein => inst_val,
pulseout => inst_reg_val,
inbusy => open
);


-- Serial interface state-machine

process (rst, serial_clk)
begin
if (rst = '1') then

init_tmp     <= '0';
init_reg     <= '0';
sh_state     <= idle;
sh_counter   <= 0;
shifting     <= '0';
read_n_write <= '0';
ncs_int      <= '1';

elsif (rising_edge(serial_clk)) then

-- Double synchonise flag from other clock domain
init_tmp <= init;
init_reg <= init_tmp;

-- Main state machine
case sh_state is

  when idle =>
    sh_counter <= shift_reg'length-data_reg'length-1; --total length minus data bytes;
    -- Accept every instruction
    if (inst_reg_val = '1' or init_reg = '1') then
      shifting     <= '1';
      read_n_write <= inst_rw and not init_reg; -- force write during init
      ncs_int      <= '0';
      sh_state     <= instruct;
    else
      shifting     <= '0';
      ncs_int      <= '1';
    end if;

  when instruct =>
    if (sh_counter = 0) then
      sh_counter <= data_reg'length-1;
      sh_state   <= data_io;
    else
      sh_counter <= sh_counter - 1;
    end if;

  when data_io =>
    if (sh_counter = 0) then
      sh_counter <= shift_reg'length-data_reg'length-1; --total length minus one data byte;
      shifting   <= '0';
      ncs_int    <= '1';
      if (read_n_write = '1') then
        sh_state <= data_valid;
      else
        sh_state <= idle;
      end if;
    else
      sh_counter <= sh_counter - 1;
    end if;

  when data_valid =>
    sh_state <= idle;

  when others =>
    sh_state <= idle;

end case;

end if;
end process;

busy <= '0' when (sh_state = idle and init_reg = '0') else '1';

Csdn user default icon
上传中...
上传图片
插入图片