- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I started writing my own custom components for the SOPC builder. But I didn't understand yet, how I can configure my own component via Nios. I still worked with generic parameters, but now I want to give my component a register space which can be accessed via Nios. How does it work? Can you please give me a hint? Best Regards! tonibLink Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
you need to create a custom component with an Avalon Memory Mapped Slave interface, and use the Nios to write to registers within your component
have you seen this video training? it may cover this area: http://www.altera.com/education/training/courses/oemb1111- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok, thanks! But how does it work exactly? Do I have to write a process which observs write transfers to my component and set a variable with the received data e.g.? Or is it possible to map addresses direct to variables?
I want to use the memory interface to configure my component, so i have to store some "variables"... Thanks for your assistance! tonib- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You have to write a process that waits for 'read' and 'write' control signals on the Avalon interface, yes.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok thanks, but how is the general usage of storing configuration registers in own components? Do you use signals which are set and read by the process waiting for 'read' and 'write' control signals? Or how do you realize this storing of data?
In my case I want to store some variables which control the behavior of my own component... Thanks!- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You almost have it.
1. Declare regs in your module to hold the parameters you need with the appropriate number of bits you require for each parameter. These are your "variables". 2. Decide which address(es) will be associated with your parameter register(s). 3. When a read or write control signal becomes active, decode the address lines (usually done with a case statement) and read or set the appropriate register. For example, to write to a parameter you might use "my_parameter_reg <= writedata;", or "my_parameter_reg[5:0] <= writedata[5:0];" if you have a configuration flags register to hold 6 boolean values. This is verilog syntax by the way. For reading, you might have something like "readdata_reg <= my_parameter_reg;", or "readdata_reg <= {26'b0, my_parameter_reg[5:0]};" and somewhere in your module "assign readdata = readdata_reg;" In this scenario, you would need 1 read waitstate to allow a specific parameter_reg to set the generic readdata_reg, which is then available to the readdata wires on the next clock. There are ways to avoid the waitstate, but you need to fairly complicated logical anding and oring operation to do so. Here is some essential snippets of code from one component I did:
assign readdata = {32 {(address == 3'b000)}} & position |
{32 {(address == 3'b001)}} & r_counter_period |
{32 {(address == 3'b010)}} & r_step_pulse_length |
{32 {(address == 3'b011)}} & r_captured_position |
{32 {(address == 3'b100)}} & r_pulse_generator_value |
{32 {(address == 3'b111)}} & {r_position_has_been_captured, encoder_error, r_control_register};
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
r_reset_position_has_been_captured <= 1'b1;
r_reset_encoder_error <= 1'b1;
r_set_counter <= 1'b1;
r_control_register <= 10'b0;
r_counter_period <= -1;
r_step_pulse_length <= 16'hFF;
r_new_counter_value <= 1'b0;
end
else begin
if (chipselect) begin
if (~write_n) begin
case (address)
3'b000: begin
r_new_counter_value <= writedata;
r_set_counter <= 1'b1;
end
3'b001: begin
r_counter_period <= writedata;
end
3'b010: begin
r_step_pulse_length <= writedata;
end
3'b011: begin
r_reset_position_has_been_captured <= 1'b1;
end
3'b100: begin
r_reset_encoder_error <= 1'b1;
end
3'b101: begin
end
3'b110: begin
end
3'b111: begin
r_control_register <= writedata;
end
endcase
end // ~write_n
end // chipselect
else begin
r_reset_encoder_error <= 1'b0;
r_reset_position_has_been_captured <= 1'b0;
r_set_counter <= 1'b0;
end
end // not in reset
end
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page