Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

registers in custom component and their address offset

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.

2 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.