hello,I want to implement a code to handle an external interrupt and in it I want to use a clear on read register. But, I couldn't find the logic for it. So, anyone can help me please???
I am trying to implement a code to detect a external interrupt by using avalon conduit interface and MM interface and in which on occurrence of interrupt read its source register and assign a zero value to it or reset it.I also need a help to implement a verilog code for MM slave which is conduit interface.
What code have you written so far? Have you written any part of your MM slave? Does it respond to your host?Get that working then we can work on the interrupt or post some code for us to help you with. Cheers, Alex
Here I posted my code for read write operation and to handle external interrupt through conduit.the commented part of this code is to solved the error but it is not the permenant solution. So, can any one have another logic for clear on read register. module ext_int_ext(clock, resetn, int0_export, int1_export, int0_irq, int1_irq, read, write, readdata, writedata, byteenable); input clock, resetn, read, write; input int0_export, int1_export; input [1:0] byteenable; input [15:0] writedata; output [15:0] readdata; output reg int0_irq, int1_irq; wire local_byteenable; reg [15:0] to_reg, readdata; wire [15:0] from_reg; reg [7:0] counter; parameter time_to_readdata = 2; reg16 U1 (.clock(clock), .resetn(resetn), .D(to_reg), .byteenable(local_byteenable), .Q(from_reg)); assign local_byteenable = byteenable; /* Interrupt 0 */ always@ (posedge clock or negedge resetn) begin if(!resetn) int0_irq <= 2'b00; else if(int0_export == 1) int0_irq <= 2'b01; else int0_irq <= 2'b00; end /* Interrupt 1 */ always@ (posedge clock or negedge resetn) begin if(!resetn) int1_irq <= 2'b00; else if((from_reg) == 1) begin if(int1_export == 1) int1_irq <= 2'b01; end else int1_irq <= 2'b00; end always@ (posedge clock or negedge resetn) begin if(!resetn) to_reg <= 16'd0; else if((from_reg) == 1) if(write == 1) to_reg <= writedata; else to_reg <= 16'd0; end /* Read */ always@ (posedge clock or negedge resetn) begin // counter <= counter - 1; // if(!resetn) // begin //// to_reg <= 16'd0; // counter <= time_to_readdata; // end if(read == 1) begin readdata <= from_reg; // if(counter == 0) // begin // to_reg <= 16'd0; // counter <= time_to_readdata; // end end // else // begin // //to_reg <= 16'd0; // counter <= time_to_readdata; // end end endmodule
Nowhere in the code are you are attempting to detect a read. You need to clear your irq registers when 'read' goes active and, depending on your requirements, when the address points to your interrupt register.At the minute your irq registers are simply going to reflect the values on int0_export & int1_export and will each clear to zero when these two signals go low. Cheers, Alex
--- Quote Start --- I want to implement a code to handle an external interrupt and in it I want to use a clear on read register. --- Quote End --- Please do not implement this logic - ever. Why? What may seem like a good idea has some unintended side effects. For example, if your device ends up on a PCIe board, if you create a design where "reads have side effects" you cannot implement read-prefetching. Read-prefetching is implemented by DMA controllers and bridges. Basically when a bridge sees a read burst, and it does not know how long the burst is, it will read "a little more" just in case. If your read-to-clear register just happens to be in the "a little more" part of the memory map - oops, your interrupt gets cleared. A better solution (you'll find it in the ARM interrupt controller registers) is write-1-to-clear. Your interrupt handler may read an interrupt status register to determine which interrupts have fired, and then it can clear just one bit but writing a 1 to the location it wants to clear. If a different interrupt bit needs to be set, then your write-back to the register does not affect the setting of that other bit. If your register was a simple write register, then writing a word with zeros in other interrupt flag locations would clear other interrupt sources on write. "Save an engineer, do not design hardware with read side-effects" Cheers, Dave
--- Quote Start --- Please do not implement this logic - ever. --- Quote End --- I'm sorry but I don't agree with this - it's too strong. Yes, there are situations where you would not implement such logic. However, the 'unintended side effects' only materialise when the behaviour of the logic is not understood by anyone using it - typically the embedded software engineer. I don't know whether kgandhi0408 is implementing a PCIe card or a system whose interrupts require long processes or memory transfers before the interrupt should be cleared. However, looking at the code posted - I doubt it. I suspect kgandhi0408 is likely to be wearing both rtl and software hats. Providing he understands the behaviour of the logic he's implemented then there won't be any unexpected side effects. More generally, providing the behaviour of the logic has been properly documented then any software engineer, who follows that documentation correctly, will not see any unexpected side effects. Those who don't read it so well will still complain of unexpected side effects... Cheers, Alex
--- Quote Start --- I'm sorry but I don't agree with this - it's too strong. --- Quote End --- Ok, fair enough. This is the internet though, so you sometimes need some shock value :) Implementing "reads with side effects" needs to be carefully considered, especially since Altera, Xilinx, and Microsemi have all adopted ARM AMBA standard, AXI3, AXI4, and AHB-Lite respectively, for their standardized IP interfaces. All of these interfaces support burst-mode accesses by default. A word of warning can spark a debate ... and the opinions shared with the world might save an engineer a headache :) Cheers, Dave