From 157301faa093f53f069792f89b5b1a0789ef7b95 Mon Sep 17 00:00:00 2001 From: Grzegorz Daniluk <grzegorz.daniluk@cern.ch> Date: Tue, 10 Sep 2013 10:02:11 +0200 Subject: [PATCH] [switch-optimization]: wb_simple_pwm: add generic to set/reduce regs size The values used in WR Switch software fit in 8-bit registers so using 16-bits in HDL was waste of resources. --- .../wishbone/wb_simple_pwm/wb_simple_pwm.vhd | 56 ++++++++++++------- .../wishbone/wb_simple_pwm/xwb_simple_pwm.vhd | 5 +- modules/wishbone/wishbone_pkg.vhd | 2 + 3 files changed, 41 insertions(+), 22 deletions(-) diff --git a/modules/wishbone/wb_simple_pwm/wb_simple_pwm.vhd b/modules/wishbone/wb_simple_pwm/wb_simple_pwm.vhd index 9d434176..d6924d52 100644 --- a/modules/wishbone/wb_simple_pwm/wb_simple_pwm.vhd +++ b/modules/wishbone/wb_simple_pwm/wb_simple_pwm.vhd @@ -6,7 +6,7 @@ -- Author : Tomasz Wlostowski -- Company : CERN BE-Co-HT -- Created : 2012-12-18 --- Last update: 2012-12-20 +-- Last update: 2013-09-10 -- Platform : FPGA-generic -- Standard : VHDL'93 ------------------------------------------------------------------------------- @@ -43,6 +43,7 @@ use work.spwm_wbgen2_pkg.all; entity wb_simple_pwm is generic( g_num_channels : integer range 1 to 8; + g_regs_size : integer range 1 to 16 := 16; g_default_period : integer range 0 to 255 := 0; g_default_presc : integer range 0 to 255 := 0; g_default_val : integer range 0 to 255 := 0; @@ -70,16 +71,29 @@ end wb_simple_pwm; architecture behavioral of wb_simple_pwm is - type t_drive_array is array(0 to g_num_channels-1) of std_logic_vector(15 downto 0); + type t_drive_array is array(0 to g_num_channels-1) of std_logic_vector(g_regs_size-1 downto 0); procedure f_handle_dr_writes(index : integer; data : std_logic_vector; load : std_logic; signal d : out t_drive_array) is begin if(index <= g_num_channels and load = '1') then - d(index-1) <= data; + d(index-1) <= data(g_regs_size-1 downto 0); end if; end f_handle_dr_writes; + function f_expand_data(dat : std_logic_vector(g_regs_size-1 downto 0)) + return std_logic_vector is + variable ret : std_logic_vector(15 downto 0); + begin + if g_regs_size = 16 then + ret := dat; + else + ret(g_regs_size-1 downto 0) := dat; + ret(15 downto g_regs_size) := (others=>'0'); + end if; + return ret; + end function; + component simple_pwm_wb port ( rst_n_i : in std_logic; @@ -103,9 +117,9 @@ architecture behavioral of wb_simple_pwm is signal regs_out : t_spwm_out_registers; signal tick : std_logic; - signal cntr_pre, cntr_main : unsigned(15 downto 0); - signal presc_val : std_logic_vector(15 downto 0); - signal period_val : std_logic_vector(15 downto 0); + signal cntr_pre, cntr_main : unsigned(g_regs_size-1 downto 0); + signal presc_val : std_logic_vector(g_regs_size-1 downto 0); + signal period_val : std_logic_vector(g_regs_size-1 downto 0); begin -- behavioral @@ -130,28 +144,28 @@ begin -- behavioral ------------------------------------------------------------------------------- p_drive_readback : process(drive) begin - regs_in.dr0_i <= drive(0); + regs_in.dr0_i <= f_expand_data(drive(0)); if(g_num_channels >= 2) then - regs_in.dr1_i <= drive(1); + regs_in.dr1_i <= f_expand_data(drive(1)); end if; if(g_num_channels >= 3) then - regs_in.dr2_i <= drive(2); + regs_in.dr2_i <= f_expand_data(drive(2)); end if; if(g_num_channels >= 4) then - regs_in.dr3_i <= drive(3); + regs_in.dr3_i <= f_expand_data(drive(3)); end if; if(g_num_channels >= 5) then - regs_in.dr4_i <= drive(4); + regs_in.dr4_i <= f_expand_data(drive(4)); end if; if(g_num_channels >= 6) then - regs_in.dr5_i <= drive(5); + regs_in.dr5_i <= f_expand_data(drive(5)); end if; if(g_num_channels >= 7) then - regs_in.dr6_i <= drive(6); + regs_in.dr6_i <= f_expand_data(drive(6)); end if; if(g_num_channels >= 8) then - regs_in.dr7_i <= drive(7); + regs_in.dr7_i <= f_expand_data(drive(7)); end if; end process; @@ -160,7 +174,7 @@ begin -- behavioral if rising_edge(clk_sys_i) then if rst_n_i = '0' then for i in 0 to g_num_channels-1 loop - drive(i) <= std_logic_vector(to_unsigned(g_default_val, 16)); + drive(i) <= std_logic_vector(to_unsigned(g_default_val, g_regs_size)); end loop; -- i else f_handle_dr_writes(1, regs_out.dr0_o, regs_out.dr0_load_o, drive); @@ -175,21 +189,21 @@ begin -- behavioral end if; end process; - regs_in.cr_presc_i <= presc_val; - regs_in.cr_period_i <= period_val; + regs_in.cr_presc_i <= f_expand_data(presc_val); + regs_in.cr_period_i <= f_expand_data(period_val); load_cr: process(clk_sys_i) begin if rising_edge(clk_sys_i) then if(rst_n_i = '0') then - presc_val <= std_logic_vector(to_unsigned(g_default_presc, 16)); + presc_val <= std_logic_vector(to_unsigned(g_default_presc, g_regs_size)); elsif(regs_out.cr_presc_load_o = '1') then - presc_val <= regs_out.cr_presc_o; + presc_val <= regs_out.cr_presc_o(g_regs_size-1 downto 0); end if; if(rst_n_i = '0') then - period_val <= std_logic_vector(to_unsigned(g_default_period, 16)); + period_val <= std_logic_vector(to_unsigned(g_default_period, g_regs_size)); elsif(regs_out.cr_period_load_o = '1') then - period_val <= regs_out.cr_period_o; + period_val <= regs_out.cr_period_o(g_regs_size-1 downto 0); end if; end if; end process; diff --git a/modules/wishbone/wb_simple_pwm/xwb_simple_pwm.vhd b/modules/wishbone/wb_simple_pwm/xwb_simple_pwm.vhd index cca0d5d7..949839d9 100644 --- a/modules/wishbone/wb_simple_pwm/xwb_simple_pwm.vhd +++ b/modules/wishbone/wb_simple_pwm/xwb_simple_pwm.vhd @@ -6,7 +6,7 @@ -- Author : Tomasz Wlostowski -- Company : CERN BE-Co-HT -- Created : 2012-12-18 --- Last update: 2012-12-20 +-- Last update: 2013-09-10 -- Platform : FPGA-generic -- Standard : VHDL'93 ------------------------------------------------------------------------------- @@ -43,6 +43,7 @@ use work.wishbone_pkg.all; entity xwb_simple_pwm is generic ( g_num_channels : integer range 1 to 8; + g_regs_size : integer range 1 to 16 := 16; g_default_period : integer range 0 to 255 := 0; g_default_presc : integer range 0 to 255 := 0; g_default_val : integer range 0 to 255 := 0; @@ -66,6 +67,7 @@ architecture wrapper of xwb_simple_pwm is component wb_simple_pwm generic ( g_num_channels : integer range 1 to 8; + g_regs_size : integer range 1 to 16 := 16; g_default_period : integer range 0 to 255; g_default_presc : integer range 0 to 255; g_default_val : integer range 0 to 255; @@ -91,6 +93,7 @@ begin -- rtl U_Wrapped_PWM : wb_simple_pwm generic map ( g_num_channels => g_num_channels, + g_regs_size => g_regs_size, g_default_period => g_default_period, g_default_presc => g_default_presc, g_default_val => g_default_val, diff --git a/modules/wishbone/wishbone_pkg.vhd b/modules/wishbone/wishbone_pkg.vhd index 722bfb86..33f22c1b 100644 --- a/modules/wishbone/wishbone_pkg.vhd +++ b/modules/wishbone/wishbone_pkg.vhd @@ -754,6 +754,7 @@ package wishbone_pkg is component wb_simple_pwm generic ( g_num_channels : integer range 1 to 8; + g_regs_size : integer range 1 to 16 := 16; g_default_period : integer range 0 to 255 := 0; g_default_presc : integer range 0 to 255 := 0; g_default_val : integer range 0 to 255 := 0; @@ -777,6 +778,7 @@ package wishbone_pkg is component xwb_simple_pwm generic ( g_num_channels : integer range 1 to 8; + g_regs_size : integer range 1 to 16 := 16; g_default_period : integer range 0 to 255 := 0; g_default_presc : integer range 0 to 255 := 0; g_default_val : integer range 0 to 255 := 0; -- GitLab