- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi All,
I've got a situation where the IUL and/or DMA components don't fit well. My chip (a USB controller) requires substancially different timing for Read and Write. Additionally this chip requires Read and Write "Recovery" times. (the minimum time before another read or write can be performed after the last one) I don't know how common recovery times are, but it would be nice to at least specify separate Read and Write timings in the IUL. The other elegant solution would be to have the dma controller accept a delay between reads/writes - preferably at runtime. This would allow specification of a "recovery time" between accesses. Anyone know a better workaround right now? I'm thinking about creating a separate IUL for read and write. Thanks, KenLink Copied
8 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For something like this, I've always had to fall back on custom logic driving the waitrequest line to the IUL.
The only other thing I can think of is creating the IUL, then editing the system.ptf file (not sure that would work, though) or creating a custom component type (based on the IUL-generated module). There are a lot of settings in the PTF files that you can't get to from the IUL GUI. As I'm still learning how to do just that, I'm afraid I can't be of more help.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Mike,
Thanks. I'm not very handy with creating my own external logic. I can do very simple things with the graphical editor and I can write simple VHDL. Anyway, I look in the .ptf and you're right there are separate Read_Wait_States and Write_Wait_States. I think I'll edit the IUL to use clocks instead of ns and play with these two values. I guess I could also edit the dma.v file to insert the recovery time perhaps. (Maybe with the HW Engineer's help http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/smile.gif ) Any additional ideas or insights appreciated. I'll post my findings. Thanks, Ken- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, it sounds like all you need for recovery time is a counter that counts down to 0 and then stops, which gets triggered (loaded) after an access. Then, when a new access comes in, if that counter isn't 0 yet, you assert waitrequest.
Here's some Verilog code that shows what I'm getting at. I can't guarantee this code, because I haven't tested (or even compiled) it. This also doesn't properly handle the case where one or more of the delay constants is 0, and it might stuff in an extra clock. There are also various failure cases (Avalon bus aborting the transfer?) that aren't taken into account, so caveat programmer...module USBInterface
(
// From Avalon bus. All are active high.
input clk,
input reset,
input read,
input write,
input chipselect,
output reg waitrequest
);
// Timing values, in CPU clocks.
localparam kReadWaitStates = 2; // I'm making all these numbers up.
localparam kWriteWaitStates = 4; // Set them to realistic values.
localparam kReadRecoveryClocks = 20;
localparam kWriteRecoveryClocks = 60;
wire doRead, doWrite;
assign doRead = read & chipselect;
assign doWrite = write & chipselect;
// Delay counter
reg delay, newDelay; // or however many bits you need.
reg start;
always @(posedge clk, posedge reset)
if(reset)
delay <= 0;
else if(start)
delay <= newDelay;
else if(delay > 0)
delay <= delay - 1;
// State Machine
reg accessState, nextState;
localparam sIdle = 0;
localparam sWaiting = 1;
localparam sActive = 3;
localparam sRecovering = 2;
always @(posedge clk, posedge reset)
if(reset)
accessState <= 0;
else
accessState <= nextState;
always @* begin
// Defaults
nextState = accessState;
start = 0;
waitrequest = 0;
newDelay = 8'bxxxxxxxx;
// States
case(accessState)
sIdle: begin
nextState = sWaiting;
start = 1;
waitrequest = 1;
if(doRead)
newDelay = kReadWaitStates - 1;
else if(doWrite)
newDelay = kWriteWaitStates - 1;
else begin // Nothing to do, stand down.
nextState = sIdle;
start = 0;
waitrequest = 0;
end
end
sWaiting: begin
if(delay == 0)
nextState = sActive;
waitrequest = 1;
end
sActive: begin
nextState = sRecovering;
start = 1;
if(doRead)
newDelay = kReadRecoveryClocks;
else
newDelay = kWriteRecoveryClocks;
end
sRecovering: begin
if(delay == 0)
nextState = sIdle;
waitrequest = doRead | doWrite;
end
endcase
end
wire interfaceActive; // This goes high for one clock after the wait states expire.
interfaceActive = accessState == sActive;
endmodule
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Mike,
Wow, thanks! Can't say I have the talent to put it to use right away, but if my .ptf file tweaking doesn't work out I'll certainly give it a whirl. I'm sure there are many here that will make immediate use of your ideas and code. I didn't get a chance to work on this today, hopefully tomorrow. Maybe someone who knows if the Read_Wait_States and Write_Wait_States are honored will chime in before I waste much time. I'm a little skepitcal since it would have been trivial yet very useful to surface these to the SOPC wizard. Ken- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Did this solve the problem?
If not tell us and we'll see if we can figure something out.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Kerri,
I just tightened my joint Read and Write timing as much as I could. It would really be nice though to either (or both) specify separate Read and Write timings or have a wait time (in cpuclocks) in between dma transfers. Maybe in a future release? My biggest problem now is getting 8MB/s of data streamed into my Nios system. Thanks, Ken- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, in our bug tracking for an enhancement. :-)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hello
is there a way to acess to data from SRAM to implement this tado to the principal programm in web server program? i use DE2 thanks
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page