Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
21592 Discussions

registers in custom component and their address offset

Altera_Forum
Honored Contributor II
1,352 Views

Hi all 

 

I'm wondering how NiosII defines the address offset for the registers in a custom component. 

 

For example, I download a PWM verilog code from internet and generate a custom component which has an Avalon-MM interface to NiosII in Qsys component editor.  

 

This is the PWM verilog code 

module avalon_pwm( clk, wr_data, cs, wr_n, addr, clr_n, rd_data, pwm_out ); input clk; input wr_data; input cs; input wr_n; input addr; input clr_n; output rd_data; output pwm_out; reg div; reg duty; reg counter; reg off; reg rd_data; wire div_en; wire duty_en; // write div or duty always@(posedge clk or negedge clr_n) begin if(clr_n == 1'b0) begin div <= 0; duty <= 0; end else begin if(div_en) div <= wr_data; if(duty_en) duty <= wr_data; end end // counter always@(posedge clk or negedge clr_n) begin if(clr_n == 1'b0) counter <= 0; else if(counter >= (div-1)) counter <= 0; else counter <= counter + 1; end // PWM always@(posedge clk or negedge clr_n) begin if(clr_n == 0) off <= 0; else if(counter >= duty) off <= 1; else if(counter == 0) off <= 0; end // read div or duty always@(addr or div or duty) begin if(addr == 0) rd_data = div; else rd_data = duty; end assign div_en = cs & !wr_n & !addr; assign duty_en = cs & !wr_n & addr; assign pwm_out = !off; endmodule  

 

When I connect this PWM component to NiosII in Qsys and set the base address to 0x00041010, the end address becomes 0x00041017. So I guess there're 8 registers which can be accessed with the IOWR/IORD marcos by a C program on NiosII. 

 

This is the code related to this PWM component in system.h 

# define ALT_MODULE_CLASS_pwm avalon_pwm # define PWM_BASE 0x41010 # define PWM_IRQ -1 # define PWM_IRQ_INTERRUPT_CONTROLLER_ID -1 # define PWM_NAME "/dev/pwm" # define PWM_SPAN 8 # define PWM_TYPE "avalon_pwm"  

 

I can use IOWR(PWM_BASE, 0, xxx) to set the div and IOWR(PWM_BASE, 1, xxx) to set the duty to have a PWM signal in different duty cycle.  

 

My question is how to know which signals in the Verilog code are corresponding to the registers from 0x00041010 to 0x00041017.
0 Kudos
2 Replies
Altera_Forum
Honored Contributor II
623 Views

Your component as only 2 32bit registers: div and duty. 

The registers are selected with a single address line: addr 

Avalon interface uses byte addressing, so your IOWR macro calls at offset 0 and 1 

will actually access physical addresses 0x00041010 and 0x00041014. 

The other non-multiple-of-4 addresses are unusable, since your component doesn't support byte nor 16bit accesses.
0 Kudos
Altera_Forum
Honored Contributor II
623 Views

Hi Chis72 

 

Thank you for your clear explanation.
0 Kudos
Reply