- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am a beginner learning Quartus. I am trying to write the HDL for a new component to make 2 LEDs blink in a system using a NIOS II processor. I'm trying to learn SystemVerilog rather than verilog. This HDL compiles without errors but is unfinished because I am still learning and and not fully certain how the avalon MM interface actually works. What is written is my understanding so far.
- Can someone please shed some light on how the addressing part works? I've been reading through the altera manuals but am starting to get muddled in all the info. I do not understand how to set addresses so that the LSB of writedata will alert my go_flag to make my hardware actually start and be enabled.
- Is my state machine correct? To get my module to show that it is in action I can just use the go_flag and the go_Flag_Start relationship to get the writedata[0] bit?
- Where can I find learn how to write the c-code for the NIOS II processor? I'm googling and see examples using commands like IOWR and stuff like that but I can't yet find resources for learning that. I know C but not these commands in C.
- Any general coding (HDL) tips are welcomed to. I look forward to hearing back. Thank you!
Here's the module and the interface for it that I've written so far:
/* Memory Map
*
* Write - 0x00
*
* Read - 0x01
*
/*
/******LEDFlash Modules *******/
module LEDFlash
(
input logic clock_50, //50MHz clock
input logic reset, // button 0
input logic enable1, //switch 0
input logic enable100Hz, // switch 2
input logic [31:0]goFlag, // Flag to start the module
// (info will come from first bit of writedata[0];
output logic state = 1'b0, //0.5sec blink LED
output logic led100Hz = 1'b0, //100Hz blink LED
// for read state
output logic readLED = 1'b0 // LED to show when the nios is sending read data
);
//Counter registers declared:
logic [24:0] counter = 25'b0; // 0.5sec counter bits start set to 0
logic [18:0] counter100Hz = 19'b0; // 100Hz counter bits starts at 0
// (ctr needs 16 bits at count up to 50,000 cycles in binary)
//Counter: count for every 0.5 seconds
always_ff @ (posedge clock_50) // at every pos clock edge do this:
begin
counter[24:0] <= counter[24:0] + 25'b1; // all counter bits = counters + 1
if (counter[24:0] == 25'd12500000) // if counter bits = 25,000,000 cycles
begin
counter[24:0] <= 25'b0; // reset counter to zero
end
end
//State: blink for 0.5 seconds
always_ff @ (posedge clock_50) // at every pos clock edge do this:
begin
if (enable1 == 1'b1)
begin
if (counter[24:0] == 25'd12500000) // if counter bits = 25,000,000 AND
// enable is ON - blink
begin
state <= ~state; // LED blinks every 25'd500,000
//(switch state from what it was previously -
// blinks on for 0.5 sec, then off for 0.5 // sec)
end
end
else
state <= 1'b0; // else, keep LED off
end
// Not sure this actually works correctly...
//100Hz counter (500,000 cycles)
always_ff @ (posedge clock_50)
begin
counter100Hz[18:0] <= counter100Hz[18:0] + 19'b1; //start counting
if (counter100Hz[18:0] == 19'd500000) //if 50,000 cycles are reached
begin
counter100Hz[18:0] <= 19'b0; //reset counter100Hz
end
end
// 100Hz blink
always_ff @ (posedge clock_50) // why always_ff? should it be always_combo?
begin
if (enable100Hz == 1'b1)
begin
if (counter100Hz[18:0] == 19'd500000)
begin
led100Hz <= ~led100Hz;
end
end
else
led100Hz <= 1'b0;
end
endmodule
/************************ The Avalon Interface ****************************/
module avs_blinking_interface (
// Signals between FPGA and NIOS:
// avs clock and reset
input logic csi_clk,
input logic rsi_rst_n,
// avs slave signals:
input logic avs_s0_read, // for a load transmission - reads/loads from master
input logic avs_s0_write, // for a store transmission - write to the master
input logic [3:0] avs_s0_address, // Why do I need an address?
input logic [31:0] avs_s0_writedata, // Comes from C code in NIOS
output logic [31:0] avs_s0_readdata // FPGA to NIOS
);
// Internal Logic
logic [0:0]goFlag_Start = 1'b0; // FYI: Would automatically be set to a 1 bit register
// Blinking LED Instantiation
LEDFlash U1 (
.Clock_50(csi_clk),
.reset (rsi_rst_n),
.goFlag(goFlag_Start)
);
// How system should work when it talks through avs:
always_ff @ (posedge csi_clk) begin
if (!rsi_rst_n) begin // If I don't press reset button (KEY0)
// If no reset, start in Idle State = nothing happening on FPGA
goFlag_Start <= 1'b0; // go_flag_Start keeps anything from happening // because it's staying low right?
if (avs_s0_write && avs_s0_address == 0) begin // if sent a write command: slave is getting // data
goFlag_Start <= avs_s0_writedata[0]; // set the go flag is based on LSB of //writedata
// State depends on go flag
case (goFlag_Start)
1'b0: begin
// don't let U1 module activate - Idle state
end
1'b1: begin
// start U1 module, start blinking - Blink state
goFlag_Start <= 1'b0; // reset goFlag
end
default: begin
//pick a default
end
endcase
end
//if read command sent:
if (avs_s0_read && avs_s0_address == 1) begin
// send something back...light up an LED?
// just so I know read is actually working
end
// reset is pressed:
else
goFlag_Start <= 1'b0; // Stay in idle state, go flag is LOW
end
end
endmodule
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There's a lot going on here. Things I've noticed:
goFlag isn't doing anything in your LEDFlash. How is it supposed to work there? Is it supposed to be what you call "enable1"?
Your LEDFlash instantiation is missing a number of the I/O defined in the module (enable1, enable100Hz, goFlag, etc.).
You don't need an address input unless there is more than 1 addressable location required for reading from or writing to. That does not look to be the case here. You could just use the avs_s0_read, avs_s0_readdata, avs_s0_write, and avs_s0_writedata signals to read from or write to goFlag_Start.
I don't see why you even need a state machine here. You already created enable signals for the flashing in the LEDFlash module and you're not doing anything more complicated than enabling or disabling the flashing.
I suggest you take a look at a number of online trainings. Search for "avalon", "platform designer", and "verilog" to find things that may be applicable:
https://www.intel.com/content/www/us/en/programmable/support/training/catalog.html
This is a good starting point for creating a custom component that will work in Platform Designer:
https://www.intel.com/content/www/us/en/programmable/support/training/course/oqsys3000.html
#iwork4intel
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Wow, thank you for so much input! I was given this project to learn Quartus/FPGA stuff. It's really interesting to me but this is a lot to learn. The end goal of the project was to use memory mapping which is why I was trying to use the read/write/readdata/writedata/address parts and I wanted the LSB of writedata to read from/write to the go_Flag_Start. I will look into all the links you suggest and hopefully be back with improvements but I'm sure more questions will arise. Thank you again!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I forgot to also mention the Avalon spec:
https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/manual/mnl_avalon_spec.pdf
#iwork4intel
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Rachel,
Refer to the previous case which addresses most of your query and has supporting documents and example.
https://forums.intel.com/s/question/0D50P00004NfSbxSAF/custom-ip-core
Regards
Anand
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page