Martin Schoeberl wrote:> JOP at 100MHz on the Altera DE2 using the 16-bit SRAM: > > Avalon: 11,322 > SimpCon: 14,760 > > So for the SRAM interface SimpCon is a clear winner ;-) > The 16-bit SRAM SimpCon solution is even faster than > the 32-bit SRAM Avalon solution.I'm not sure what your point is. It's hardly surprising that a JOP works better with the interface it was codesigned with, rather than some other one crafted on top. It says nothing is the relative merits of Avalon and SimpCon. I could code up a counter example quite easily. Altera has an App note on "Using Nios II Tightly Coupled Memory Tutorial" (http://altera.com/literature/tt/tt_nios2_tightly_coupled_memory_tutorial.pdf), but as far as I understand you, this is already how you use the memory. I noticed you didn't reply to how SimpCon doesn't scale. Does your silence mean that you see it now? :-) Tommy
JOP as SOPC component
Started by ●August 11, 2006
Reply by ●August 18, 20062006-08-18
Reply by ●August 22, 20062006-08-22
From: "Tommy Thorn" <tommy.thorn@gmail.com> Newsgroups:> Martin Schoeberl wrote: >> JOP at 100MHz on the Altera DE2 using the 16-bit SRAM: >> >> Avalon: 11,322 >> SimpCon: 14,760 >> >> So for the SRAM interface SimpCon is a clear winner ;-) >> The 16-bit SRAM SimpCon solution is even faster than >> the 32-bit SRAM Avalon solution. > > I'm not sure what your point is. It's hardly surprising that a JOP > works better with the interface it was codesigned with, rather than > some other one crafted on top. It says nothing is the relative merits > of Avalon and SimpCon. I could code up a counter example quite easily.You're right from your point of view. I have only JOP to compare SimpCon and Avalon. JOP takes advantage of the early acknowledge of SimpCon. However, it's still simpler with SimpCon to implement a SRAM interface with the input and output registers at the IO cells in the FPGA without adding one cycle latency. A small defense of the JOP/SimpCon version: SimpCon was added very late to JOP. Up to this time JOP used it's own proprietary memory interface that was not shared with the IO subsystem. The IO devices also used a proprietary interface. Than I changed JOP to use Wishbone for memory and IO, but had to add a non Wishbone compliant early ack signal to get the performance I wanted. This resulted in the definition of SimpCon and another change in JOPs memory/IO system. It would be interesting to take another CPU (not NIOS or JOP) and implement an Avalon and a SimpCon SRAM interface and compare the performance. However, who has time to do this...> > Altera has an App note on "Using Nios II Tightly Coupled Memory > Tutorial" > (http://altera.com/literature/tt/tt_nios2_tightly_coupled_memory_tutorial.pdf), > but as far as I understand you, this is already how you use the memory.Very interesting, thanks for the link. No, this is not the way I used the on-chip memory with JOP - this looks NIOS specific. And it is stated there: 'The term tightly coupled memory interface refers to an *Avalon-like* interface...' That's interesting as it is an indication that there are issues for low latency connections with Avalon ;-)> I noticed you didn't reply to how SimpCon doesn't scale. Does your > silence mean that you see it now? :-)It means I have not thought enough about it ;-) Martin
Reply by ●August 23, 20062006-08-23
Martin Schoeberl wrote:> From: "Tommy Thorn" <tommy.thorn@gmail.com> Newsgroups: > > > Martin Schoeberl wrote: > >> JOP at 100MHz on the Altera DE2 using the 16-bit SRAM: > >> > >> Avalon: 11,322 > >> SimpCon: 14,760 > >> > >> So for the SRAM interface SimpCon is a clear winner ;-) > >> The 16-bit SRAM SimpCon solution is even faster than > >> the 32-bit SRAM Avalon solution. > > > > I'm not sure what your point is. It's hardly surprising that a JOP > > works better with the interface it was codesigned with, rather than > > some other one crafted on top. It says nothing is the relative merits > > of Avalon and SimpCon. I could code up a counter example quite easily. > > You're right from your point of view. I have only JOP to compare > SimpCon and Avalon. JOP takes advantage of the early acknowledge of > SimpCon. However, it's still simpler with SimpCon to implement a > SRAM interface with the input and output registers at the IO > cells in the FPGA without adding one cycle latency. >We talked a bit about this early on in the thread, but I think that is simply because of how you chose to implement the SRAM controller simply by only using SOPC Builder to create that Avalon slave device and external signals to the SRAM.> A small defense of the JOP/SimpCon version: SimpCon was added very > late to JOP. Up to this time JOP used it's own proprietary memory > interface that was not shared with the IO subsystem. The IO devices > also used a proprietary interface. Than I changed JOP to use > Wishbone for memory and IO, but had to add a non Wishbone compliant > early ack signal to get the performance I wanted. This resulted in > the definition of SimpCon and another change in JOPs memory/IO > system. > > It would be interesting to take another CPU (not NIOS or JOP) and > implement an Avalon and a SimpCon SRAM interface and compare the > performance. However, who has time to do this... >Never the time ;) I did take a quick look though at the jop\sopc\components\jop_avalon\class.ptf (which I think is the SOPC component file for your processor) and jop\quartus\sopcmin\jop_system.ptf (which looks to be the SOPC Builder 'system.ptf' file for the entire system) from what is on OpenCores.org. Upon quick perusal (like you said, never the time) I didn't see any use of the Avalon bus 'readdatavalid' signal (in addition to the obligatory 'waitrequest'). This implies that the master devices are being controlled strictly via the Avalon 'waitrequest' signal. The lack of use of Avalon's 'readdatavalid' I think could explain some or all of the performance differences that you're seeing between Avalon and SimpCon. To make use of it, both the master and slave side need to have the 'readdatavalid' signals implemented. If either side does not have 'readdatavalid', then SOPC Builder builds the appropriate interconnect logic but basically will end up implementing the same thing as if only 'waitrequest' was used as you have in your design. My guess is that use of 'waitrequest' and 'readdatavalid' should end up being equivalent to the SimpCon implementation.> > > > Altera has an App note on "Using Nios II Tightly Coupled Memory > > Tutorial" > > (http://altera.com/literature/tt/tt_nios2_tightly_coupled_memory_tutorial.pdf), > > but as far as I understand you, this is already how you use the memory. > > Very interesting, thanks for the link. No, this is not the way I > used the on-chip memory with JOP - this looks NIOS specific. And it > is stated there: > > 'The term tightly coupled memory interface refers to an > *Avalon-like* interface...' > > That's interesting as it is an indication that there are issues for > low latency connections with Avalon ;-) >I don't think it's so much an Avalon 'issue' as it is a statement that there are things you need to do properly to get high performance and low latency that go above and beyond the lower performance (but perhaps 'quicker' to implement) ways. Wishbone goes beyond their 'normal' transaction to sort of define some tag signals that one can use. From an earlier post it sounded like you extended SimpCon in some fashion to handle this case also. Avalon has 'waitrequest' and 'readdatavalid' built right into their basic protocol for maximum performance but also allows components to not use them if they so desire (with SOPC Builder building the appropriate connection logic for you) in exchange for not getting the highest performance. KJ
Reply by ●August 23, 20062006-08-23
> We talked a bit about this early on in the thread, but I think that is > simply because of how you chose to implement the SRAM controller > simply by only using SOPC Builder to create that Avalon slave device > and external signals to the SRAM.Nope, I did both versions: With a VHDL design and just the SOPC builder (non VHDL) version.>> It would be interesting to take another CPU (not NIOS or JOP) and >> implement an Avalon and a SimpCon SRAM interface and compare the >> performance. However, who has time to do this... >> > Never the time ;) I did take a quick look though at the > jop\sopc\components\jop_avalon\class.ptf (which I think is the SOPC > component file for your processor) and > jop\quartus\sopcmin\jop_system.ptf (which looks to be the SOPC Builder > 'system.ptf' file for the entire system) from what is on OpenCores.org.Ok, cool ;-)> Upon quick perusal (like you said, never the time) I didn't see any > use of the Avalon bus 'readdatavalid' signal (in addition to the > obligatory 'waitrequest'). This implies that the master devices are > being controlled strictly via the Avalon 'waitrequest' signal.Yes, that's true. In the general case the master (JOP) does not issue more than one read request (exception is cache load). And in this case 'readdatavalid' is of no additional use. 'readdatavalid' does only help with pipelined requests when: a.) the master can issue a new request even when the former is outstanding b.) the slave implements a FIFO to queue those requests c.) AFAIK when the request goes to the same slave (???) In a single plain read you don't get a single cycle less latency with 'readdatavalid'. The issue is that JOP relys on the early ack to reduce the latency. And this is also the case for the cache load. 'readdatavalid' does not save a single cycle for my case, sorry. I would need to redesign the cache load to issue more read command. That's the only point where I could adapt JOP to the Avalon (Wishbone,...) way.> The lack of use of Avalon's 'readdatavalid' I think could explain some > or all of the performance differences that you're seeing between Avalon > and SimpCon. To make use of it, both the master and slave side need to > have the 'readdatavalid' signals implemented. If either side does notand of course some FIFO pipelining in the SRAM slave, which adds latency for the 'normal' case.> have 'readdatavalid', then SOPC Builder builds the appropriate > interconnect logic but basically will end up implementing the same > thing as if only 'waitrequest' was used as you have in your design.agree> My guess is that use of 'waitrequest' and 'readdatavalid' should end up > being equivalent to the SimpCon implementation. > >> > >> > Altera has an App note on "Using Nios II Tightly Coupled Memory >> > Tutorial" >> > (http://altera.com/literature/tt/tt_nios2_tightly_coupled_memory_tutorial.pdf), >> > but as far as I understand you, this is already how you use the memory. >> >> Very interesting, thanks for the link. No, this is not the way I >> used the on-chip memory with JOP - this looks NIOS specific. And it >> is stated there: >> >> 'The term tightly coupled memory interface refers to an >> *Avalon-like* interface...' >> >> That's interesting as it is an indication that there are issues for >> low latency connections with Avalon ;-) >> > I don't think it's so much an Avalon 'issue' as it is a statement that > there are things you need to do properly to get high performance and > low latency that go above and beyond the lower performance (but perhaps > 'quicker' to implement) ways.If it would be a 'real' Avalon interface, just without the arbritration part, than they should offer this additional Avalon communication link for others to attach the main memory to the NIOS.> Wishbone goes beyond their 'normal' transaction to sort of define some > tag signals that one can use. From an earlier post it sounded like youAgree, pipelined trasnactions should be built into the specification and not be an add-on.> extended SimpCon in some fashion to handle this case also. Avalon hasMy pipeline approach is just this little funny busy counter instead of a single ack and that a slave has to declare it's pipeline level (0 to 3). Level 1 is almost ever possible. It's more or less for free in a slave. Level 1 means that the master can issue the next read/write command in the same cycle when the data is available (rdy_cnt=0). Level 2 means issue the next command one cycle earlier (rdy_cnt=1). Still not a big issue for a slave (especially for a memory slave where you need a little state machine anyway). Figure 4 in http://www.opencores.org/cvsweb.cgi/~checkout~/simpcon/doc/simpcon.pdf should explain it. However, it looks like I have to draw it more clearer...> 'waitrequest' and 'readdatavalid' built right into their basic protocol > for maximum performance but also allows components to not use them if > they so desire (with SOPC Builder building the appropriate connection > logic for you) in exchange for not getting the highest performance.Enjoy this discussion :-) Martin
Reply by ●August 23, 20062006-08-23
> Martin Schoeberl wrote: >>>> Another point is, in my opinion, the wrong role who has to hold data >>>> for more than one cycle. This is true for several busses (e.g. also >>>> Wishbone). For these busses the master has to hold address and write >>>> data till the slave is ready. This is a result from the backplane >>>> bus thinking. In an SoC the slave can easily register those signals >>>> when needed longer and the master can continue. >>> When happens then when you issue another request to a slave which hasn't finished processing the first? Any queue will be finite >>> and eventually you'd have to deal with stalling anyway. Any issue is that there are generally many more slaves than masters so >>> it makes sense to move the complication to the master. >> >> I disagree ;-) >> How hard is it for a slave to hold the read data more than one cycle? >> Until the next read data is requested and available? That comes almost >> for free. It's a single register, trivial logic. Ok, is a little overhead >> for an on-chip peripheral. However, you need usually a MUX in the >> peripheral for select the IO registers (now using register with a different >> meaning). Making this MUX registered is almost for free. > > Focusing on the overhead for one slave supporting one outstanding command is missing the point.However, holding data out in the slave until overwritten by new data from a new request is still worth doing it. It will simplify a single master. And probably also the interconnection logic for multiple masters.> Non-trivial slaves can support multiple simultaneous outstanding requests (say N), so they would need at least a queue N deep. > Not a problem. Now, I have multiple slaves and multiple masters on the interconnect. Each master must be able to have at least M > outstanding requests. Any one slave can only accept one request pr cycle so the interconnect (the arbitration) needs buffer the > requests in lots of FIFOs and _they_ add significant latency, logic, and complication (pick two).If you want them to be completely independent you also need a reordering of results (or some kind of transaction id) in your interconnect. For me that's a completely different game. I think that's more a Network-on-Chip (NoC) topic. NoC is a big buzz-word these days ;-)> I'll need to study SimpCon more to understand what you mean by it's support for multiple outstanding requests. Just to clarify, > I'm talking about completely independent requests, not bursts. Different masters may issue multiple of these (up to some limit) > while previously issued requests are still not complete. I do insist the requests complete in the order they were issued, mostly > to simplify things (such as the arbitration). Really just a subset of Avalon. >You can issue completely requests with the plain SimpCon specification only to 'some' extent. Only when a former request is 'yet to arrive' you can issue a new request to SimpCon (or the switch logic). That's a restriction. We could add a accept signal to allow the master to issue more requests. However, issuing multiple requests to different slaves and than delivering them in order is a pain for the switch logic. You have to remember your request order and handle the results arriving in a different order. However, for this issue a slave that holds the data till used can simplify the switching a little bit... Perhaps I should state how I see SimpCon: A *simple* SoC interconnect that allows for lower latency and pipelining to some extent. The main application I have in mind is a single master (CPU) with multiple slaves (memory and IO). The interconnect/address decoding should be simple - and it is - see an example at: http://www.opencores.org/cvsweb.cgi/~checkout~/jop/vhdl/scio/scio_min.vhd Besides component declaration and IO signal routing the interconnect is just 18 lines of VHDL. The read MUX is driven by registered select, which helps in the critical path when you have planty of slaves. Martin
Reply by ●August 24, 20062006-08-24
This is a multi-part message in MIME format. --------------000504020509080806000907 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit> However, issuing multiple requests to different slaves and > than delivering them in order is a pain for the switch > logic. You have to remember your request order and handle > the results arriving in a different order. However, for > this issue a slave that holds the data till used can > simplify the switching a little bit...See attachment. I do that in 137 line of simple Verilog, but of course it depends on slaves replying to requests in the order received.> Perhaps I should state how I see SimpCon: A *simple* > SoC interconnect that allows for lower latency and > pipelining to some extent. The main application I have > in mind is a single master (CPU) with multiple slaves > (memory and IO). The interconnect/address decoding > should be simple - and it is - see an example at: > http://www.opencores.org/cvsweb.cgi/~checkout~/jop/vhdl/scio/scio_min.vhdWell, then it's not an alternative to Avalon or WISHBONE. Multimaster is an absolute requirement for many designs and multiple outstanding requests ("pipelined" in Avalon lingo) is needed for performance. You are obviously fully free to do whatever you want, but this discussion started with a desire for a open/free interconnect fabric alternative to WISHBONE. The subset of Avalon I use is *simple* IMO. I'd be happy to show you everything, but the only remotely complicated part is what I attached. I'll ponder on your "slaves buffer readdata" idea, but whoever designed Avalon must have considered it.> Besides component declaration and IO signal routing > the interconnect is just 18 lines of VHDL. The read > MUX is driven by registered select, which helps in > the critical path when you have planty of slaves.I have n-1 arbitration structure for n masters. The interface overhead in slaves themselves are too trivial to count, but I have many more slaves than arbitration. If logic resources are the prime concern, then you should keep the interface overhead in slaves as simple as possible. Forcing them to buffer readdata doesn't sound like a simplification. I do like the apparent symmetry between the input and output ports this entails. Cheers, Tommy --------------000504020509080806000907 Content-Type: text/plain; name="arbitration.v" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="arbitration.v" module arbitration (input clock // Master port 1 ,input transfer_request1 ,input [31:0] address1 ,input wren1 ,input [31:0] wrdata1 ,input [ 3:0] wrmask1 ,output wait_request1 ,output read_data_valid1 ,output [31:0] read_data1 // Master port 2 ,input transfer_request2 ,input [31:0] address2 ,input wren2 ,input [31:0] wrdata2 ,input [ 3:0] wrmask2 ,output wait_request2 ,output read_data_valid2 ,output [31:0] read_data2 // Target port ,output transfer_request ,output [31:0] address ,output wren ,output [31:0] wrdata ,output [ 3:0] wrmask ,input wait_request ,input read_data_valid ,input [31:0] read_data ); /* * Data routing fifo. Size must cover all potential outstanding * transactions. */ parameter FIFO_SIZE_LG2 = 4; parameter debug = 0; reg data_for_1[(1 << FIFO_SIZE_LG2) - 1:0]; reg [FIFO_SIZE_LG2-1:0] rp = 0; reg [FIFO_SIZE_LG2-1:0] wp = 0; wire [FIFO_SIZE_LG2-1:0] wp_next = wp + 1; wire [FIFO_SIZE_LG2-1:0] rp_next = rp + 1; assign transfer_request = transfer_request1 | transfer_request2; assign read_data1 = read_data; assign read_data2 = read_data; assign read_data_valid1 = read_data_valid & data_for_1[rp]; assign read_data_valid2 = read_data_valid & ~data_for_1[rp]; wire en1 = transfer_request1 & ~wait_request1; wire en2 = transfer_request2 & ~wait_request2; assign address = en1 ? address1 : address2; assign wren = en1 ? wren1 : wren2; assign wrdata = en1 ? wrdata1 : wrdata2; assign wrmask = en1 ? wrmask1 : wrmask2; always @(posedge clock) begin if ((en1 | en2) & ~wren) begin data_for_1[wp] <= en1; wp <= wp_next; if (wp_next == rp) if(debug)$display("%05d ARB: FIFO OVERFLOW! wp: %d rp: %d", $time, wp_next, rp); else if(debug)$display("%05d ARB: FIFO remembered a read req wp: %d rp: %d", $time, wp_next, rp); end if (read_data_valid) begin rp <= rp_next; if (rp == wp) if(debug)$display("%05d ARB: FIFO UNDERFLOW! wp: %d rp: %d", $time, wp, rp_next); else if(debug)$display("%05d ARB: FIFO routed read data wp: %d rp: %d", $time, wp_next, rp); end end /* * Share based */ parameter SHARES_1 = 5; // > 0 parameter SHARES_2 = 10; // > 0 parameter LIKE_AVALON = 1; parameter OVERFLOW_BIT = 6; reg current_master = 0; reg [OVERFLOW_BIT:0] countdown = SHARES_1 - 2; assign wait_request1 = wait_request | transfer_request2 & current_master; assign wait_request2 = wait_request | transfer_request1 & ~current_master; reg [31:0] count1 = 1, count2 = 1; always @(posedge clock) begin if (transfer_request1 | transfer_request2) if(debug) $display("%05d ARB: Req %d/%d Arbit %d/%d W:%d %d (shares left %d, cummulative ratio %f)", $time, transfer_request1, transfer_request2, transfer_request1 & ~wait_request1, transfer_request2 & ~wait_request2, wren1, wren2, countdown + 2, 1.0 * count1 / count2); /* statistics */ count1 <= count1 + (transfer_request1 & ~wait_request1); count2 <= count2 + (transfer_request2 & ~wait_request2); /* The arbitration is only relevant when two masters try to * initiate at the same time. We swap priorities when the * current master runs out of shares. * * Notice, unlike Avalon, a master does not forfeit its shares if * it temporarily skips a request. IMO this leads to better QOS * for a master that initiates on a less frequent rate. * * In this model, the arbitration tries to approximate a * SHARES_1 : SHARE_2 ratio for Master 1 and Master 2 * transactions (as much as the available requests will allow it). */ if (~wait_request) begin if (transfer_request1 | transfer_request2) begin countdown <= countdown - 1; if (countdown[OVERFLOW_BIT]) begin current_master <= ~current_master; countdown <= (current_master ? SHARES_1 - 2 : SHARES_2 - 2); end end end end endmodule --------------000504020509080806000907--





