1.AVALON_SLAVE_PWM_CLOCK_DIVIDE_REG : PWM时钟分频寄存器.(32位)
2.AVALON_SLAVE_PWM_DUTY_CYCYLE_REG : PWM占空比寄存器.(32位)
3.AVALON_SLAVE_PWM_ENABLE_REG : PWM使能寄存器.(1位)
4.AVALON_SLAVE_PWM_IRQ_ENABLE_REG : PWM中断使能寄存器.(1位)
1. avalon_slave_pwm.vhd 为顶层文件,描述了PWM内部组件的连结关系以及内部组件与外部AVALON总线的连接关系
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY work;
ENTITY avalon_slave_pwm IS
port
(
csi_pwm_clock : IN STD_LOGIC;
avs_pwm_reset_n : IN STD_LOGIC;
avs_pwm_chipselect : IN STD_LOGIC;
avs_pwm_write : IN STD_LOGIC;
avs_pwm_read : IN STD_LOGIC;
avs_pwm_address : IN STD_LOGIC_VECTOR(2 downto 0);
avs_pwm_writedata : IN STD_LOGIC_VECTOR(31 downto 0);
ins_pwm_irq : OUT STD_LOGIC;
pwm_out : OUT STD_LOGIC;
avs_pwm_readdata : OUT STD_LOGIC_VECTOR(31 downto 0)
);
END avalon_slave_pwm;
ARCHITECTURE bdf_type OF avalon_slave_pwm IS
component pwm_task_logic
PORT(clock : IN STD_LOGIC;
reset_n : IN STD_LOGIC;
clr_irqflag : IN STD_LOGIC;
pwm_enable : IN STD_LOGIC;
clock_divide : IN STD_LOGIC_VECTOR(31 downto 0);
duty_cycle : IN STD_LOGIC_VECTOR(31 downto 0);
irq_flagset : OUT STD_LOGIC;
pwm_out : OUT STD_LOGIC
);
end component;
component pwm_register_file
PORT(csi_pwm_clock : IN STD_LOGIC;
avs_pwm_reset_n : IN STD_LOGIC;
avs_pwm_chipselect : IN STD_LOGIC;
avs_pwm_write : IN STD_LOGIC;
avs_pwm_read : IN STD_LOGIC;
irq_flag : IN STD_LOGIC;
avs_pwm_address : IN STD_LOGIC_VECTOR(2 downto 0);
avs_pwm_writedata : IN STD_LOGIC_VECTOR(31 downto 0);
ins_pwm_irq : OUT STD_LOGIC;
clr_irq : OUT STD_LOGIC;
pwm_enable : OUT STD_LOGIC;
avs_pwm_readdata : OUT STD_LOGIC_VECTOR(31 downto 0);
pwm_clock_divide : OUT STD_LOGIC_VECTOR(31 downto 0);
pwm_duty_cycle : OUT STD_LOGIC_VECTOR(31 downto 0)
);
end component;
signal SYNTHESIZED_WIRE_0 : STD_LOGIC;
signal SYNTHESIZED_WIRE_1 : STD_LOGIC;
signal SYNTHESIZED_WIRE_2 : STD_LOGIC_VECTOR(31 downto 0);
signal SYNTHESIZED_WIRE_3 : STD_LOGIC_VECTOR(31 downto 0);
signal SYNTHESIZED_WIRE_4 : STD_LOGIC;
BEGIN
b2v_inst : pwm_task_logic
PORT MAP(clock => csi_pwm_clock,
reset_n => avs_pwm_reset_n,
clr_irqflag => SYNTHESIZED_WIRE_0,
pwm_enable => SYNTHESIZED_WIRE_1,
clock_divide => SYNTHESIZED_WIRE_2,
duty_cycle => SYNTHESIZED_WIRE_3,
irq_flagset => SYNTHESIZED_WIRE_4,
pwm_out => pwm_out);
b2v_inst1 : pwm_register_file
PORT MAP(csi_pwm_clock => csi_pwm_clock,
avs_pwm_reset_n => avs_pwm_reset_n,
avs_pwm_chipselect => avs_pwm_chipselect,
avs_pwm_write => avs_pwm_write,
avs_pwm_read => avs_pwm_read,
irq_flag => SYNTHESIZED_WIRE_4,
avs_pwm_address => avs_pwm_address,
avs_pwm_writedata => avs_pwm_writedata,
ins_pwm_irq => ins_pwm_irq,
clr_irq => SYNTHESIZED_WIRE_0,
pwm_enable => SYNTHESIZED_WIRE_1,
avs_pwm_readdata => avs_pwm_readdata,
pwm_clock_divide => SYNTHESIZED_WIRE_2,
pwm_duty_cycle => SYNTHESIZED_WIRE_3);
END;
2.pwm_register_file.vhd描述了PWM内部寄存器的读写操作
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY pwm_register_file IS
PORT
(
-- INPUT
csi_pwm_clock : IN STD_LOGIC;
avs_pwm_reset_n : IN STD_LOGIC;
avs_pwm_chipselect : IN STD_LOGIC;
avs_pwm_address : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
avs_pwm_write : IN STD_LOGIC;
avs_pwm_writedata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
avs_pwm_read : IN STD_LOGIC;
irq_flag : IN STD_LOGIC;
-- OUTPUT
avs_pwm_readdata : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
pwm_clock_divide : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
pwm_duty_cycle : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
ins_pwm_irq : OUT STD_LOGIC;
clr_irq : OUT STD_LOGIC;
pwm_enable : OUT STD_LOGIC
);
END ENTITY;
ARCHITECTURE behave OF pwm_register_file IS
CONSTANT CLOCK_DIVIDE_REG_INIT : STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS => '0');
CONSTANT DUTY_CYCLE_REG_INIT : STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS => '0');
CONSTANT ZERO : STD_LOGIC_VECTOR(30 DOWNTO 0) := (OTHERS => '0');
CONSTANT CLOCK_DIVIDE : STD_LOGIC_VECTOR(2 DOWNTO 0) := "000";
CONSTANT DUTY_CYCLE : STD_LOGIC_VECTOR(2 DOWNTO 0) := "001";
CONSTANT ENABLE_PWM : STD_LOGIC_VECTOR(2 DOWNTO 0) := "010";
CONSTANT ENABLE_IRQ : STD_LOGIC_VECTOR(2 DOWNTO 0) := "011";
CONSTANT CLR_IRQ_FLAG : STD_LOGIC_VECTOR(2 DOWNTO 0) := "100";
SIGNAL clock_divide_r : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL duty_cycle_r : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL enable_pwm_r : STD_LOGIC;
SIGNAL enable_irq_r : STD_LOGIC;
SIGNAL clr_irq_flag_r : STD_LOGIC;
SIGNAL readdata_r : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL write_act : STD_LOGIC;
SIGNAL read_act : STD_LOGIC;
BEGIN
write_act <= avs_pwm_chipselect AND avs_pwm_write;
read_act <= avs_pwm_chipselect AND avs_pwm_read;
-- Register Write
Register_Write:PROCESS(csi_pwm_clock,avs_pwm_reset_n)
BEGIN
IF avs_pwm_reset_n = '0' THEN
clock_divide_r <= CLOCK_DIVIDE_REG_INIT;
duty_cycle_r <= DUTY_CYCLE_REG_INIT;
enable_pwm_r <= '0';
enable_irq_r <= '0';
ELSIF RISING_EDGE(csi_pwm_clock) THEN
IF write_act = '1' THEN
CASE avs_pwm_address IS
WHEN CLOCK_DIVIDE => clock_divide_r <= avs_pwm_writedata;
WHEN DUTY_CYCLE => duty_cycle_r <= avs_pwm_writedata;
WHEN ENABLE_PWM => enable_pwm_r <= avs_pwm_writedata(0);
WHEN ENABLE_IRQ => enable_irq_r <= avs_pwm_writedata(0);
WHEN OTHERS => NULL;
END CASE;
END IF;
END IF;
END PROCESS Register_Write;
ClrIrqFlag_Reg_Write:PROCESS(csi_pwm_clock,avs_pwm_reset_n)
BEGIN
IF avs_pwm_reset_n = '0' THEN
clr_irq_flag_r <= '0';
ELSIF RISING_EDGE(csi_pwm_clock) THEN
IF irq_flag = '1' THEN
IF write_act = '1' THEN
IF avs_pwm_address = CLR_IRQ_FLAG THEN
clr_irq_flag_r <= '1';
ELSE
NULL;
END IF;
END IF;
ELSE
clr_irq_flag_r <= '0';
END IF;
END IF;
END PROCESS ClrIrqFlag_Reg_Write;
IrqFlag_Clr:PROCESS(csi_pwm_clock)
BEGIN
IF FALLING_EDGE(csi_pwm_clock) THEN
IF clr_irq_flag_r = '1' THEN
clr_irq <= '1';
ELSE
clr_irq <= '0';
END IF;
ELSE
NULL;
END IF;
END PROCESS IrqFlag_Clr;
-- Register Read
Register_Read:PROCESS(read_act,avs_pwm_address,clock_divide_r,duty_cycle_r,enable_pwm_r)
BEGIN
IF read_act = '1' THEN
CASE avs_pwm_address IS
WHEN CLOCK_DIVIDE => readdata_r <= clock_divide_r;
WHEN DUTY_CYCLE => readdata_r <= duty_cycle_r;
WHEN ENABLE_PWM => readdata_r <= ZERO & enable_pwm_r;
WHEN ENABLE_IRQ => readdata_r <= ZERO & enable_irq_r;
WHEN CLR_IRQ_FLAG => readdata_r <= ZERO & clr_irq_flag_r;
WHEN OTHERS => readdata_r <= (OTHERS => '0');
END CASE;
END IF;
END PROCESS Register_Read;
avs_pwm_readdata <= readdata_r;
pwm_clock_divide <= clock_divide_r;
pwm_duty_cycle <= duty_cycle_r;
pwm_enable <= enable_pwm_r;
ins_pwm_irq <= enable_irq_r AND irq_flag;
END behave;