This list is for discussion of the design and implementation of field-programmable gate array based processors and integrated systems. It is also for discussion and community support of the XSOC Project (see http://www.fpgacpu.org/xsoc).
|
Hi there, just a quick question... Anyone know of any examples of generating sound using an FPGA. Sommit like the equivalent of a PC SoundBlaster etc?!? thanks in advance. Jamie |
|
|
|
Hi, > -----Mensaje original----- > De: Jamie Stanley [mailto:] > Enviado el: martes 2 de abril de 2002 14:44 > Para: ' > Asunto: [fpga-cpu] Sound on an FPGA? > Hi there, just a quick question... > > Anyone know of any examples of generating sound using an FPGA. > Sommit like the equivalent of a PC SoundBlaster etc?!? That's very easy having only a simple DAC converter. This ones ilustrate it using a Xess board (www.xess.com, where you can find the electrical schemes of how the dac converter is attached to the fpga): http://www.dacya.ucm.es/mendias/143/proyectos/alarma.vhdl.zip http://www.dacya.ucm.es/mendias/143/proyectos/dsp.vhdl.zip Greetings, Javier Basilio Pérez Ramas INDRA |
|
|
|
See also XAPP154: Virtex Synthesizable Delta-Sigma DAC, http://www.xilinx.com/xapp/xapp154.pdf, and its partner, XAPP155: Virtex Analog to Digital Converter, http://www.xilinx.com/xapp/xapp155.pdf. Jan Gray, Gray Research LLC |
|
I've done a simple sigma delta ADC with an ACEX 1k. It even worked without a comperator (just two R's and one C as external hardware). But don't expect a good reolution over temperture without a comperator. You can find the VHDL code at www.jopdesign.com Martin ----- Original Message ----- From: "Jamie Stanley" <> To: <> Sent: Tuesday, April 02, 2002 2:44 PM Subject: [fpga-cpu] Sound on an FPGA? > Hi there, just a quick question... > > Anyone know of any examples of generating sound using an FPGA. > Sommit like the equivalent of a PC SoundBlaster etc?!? > > thanks in advance. > Jamie > > To post a message, send it to: > To unsubscribe, send a blank message to: |
|
|
|
HI guys, I am looking to implement a Bus Arbiter in VHdl for my design. Right now I have just 8 hosts (or devices) who request access for the Bus. Each of them request for access and then get back an ACk when it is there turn. Along with a priority arbitation I also need the arbiter to store all requests that are made even when someone else is using the BUs. I have written a Sequential code which works fine in simulation but when i try to implement it in hardware(xess Virtex 800 at 25MHz.) it does NOT work. I even tried to verify after implementation and yet it does not work. :( Do u guys know of some better way of doing this. How does PCI or ISA fo something like this. This is the code that I wrote. Thought it shoudl work. let me know if u guys think i am doing something wron. Thanks Sumeet Code: PROCESS(CLK) VARIABLE COUNT : INTEGER RANGE 0 TO 15; VARIABLE COUNTA : INTEGER RANGE 0 TO 15; VARIABLE COUNTB : INTEGER RANGE 0 TO 15; VARIABLE COUNTC : INTEGER RANGE 0 TO 15; VARIABLE COUNTD : INTEGER RANGE 0 TO 15; VARIABLE COUNTE : INTEGER RANGE 0 TO 15; VARIABLE COUNTF : INTEGER RANGE 0 TO 15; VARIABLE COUNTG : INTEGER RANGE 0 TO 15; VARIABLE COUNTH : INTEGER RANGE 0 TO 15; BEGIN IF CLK' EVENT AND CLK = '1' THEN IF BREQ(0) = '1' THEN IF COUNTA = 0 THEN COUNT := COUNT + 1; COUNTA := COUNT; END IF; END IF; IF BREQ(1) = '1' THEN IF COUNTB = 0 THEN COUNT := COUNT + 1; COUNTB := COUNT; END IF; END IF; IF BREQ(2) = '1' THEN IF COUNTC = 0 THEN COUNT := COUNT + 1; COUNTC := COUNT; END IF; END IF; IF BREQ(3) = '1' THEN IF COUNTD = 0 THEN COUNT := COUNT + 1; COUNTD := COUNT; END IF; END IF; IF BREQ(4) = '1' THEN IF COUNTE = 0 THEN COUNT := COUNT + 1; COUNTE := COUNT; END IF; END IF; IF BREQ(5) = '1' THEN IF COUNTF = 0 THEN COUNT := COUNT + 1; COUNTF := COUNT; END IF; END IF; IF BREQ(6) = '1' THEN IF COUNTG = 0 THEN COUNT := COUNT + 1; COUNTG := COUNT; END IF; END IF; IF BREQ(7) = '1' THEN IF COUNTH = 0 THEN COUNT := COUNT + 1; COUNTH := COUNT; END IF; END IF; IF EN = '0' and COUNT >= 1 THEN IF COUNTA = 1 and LBACK = "00000000" THEN LBACK <= "00000001"; ELSIF COUNTB = 1 and LBACK = "00000000"THEN LBACK <= "00000010"; ELSIF COUNTC = 1 and LBACK = "00000000"THEN LBACK <= "00000100"; ELSIF COUNTD = 1 and LBACK = "00000000"THEN LBACK <= "00001000"; ELSIF COUNTE = 1 and LBACK = "00000000"THEN LBACK <= "00010000"; ELSIF COUNTF = 1 and LBACK = "00000000"THEN LBACK <= "00100000"; ELSIF COUNTG = 1 and LBACK = "00000000"THEN LBACK <= "01000000"; ELSIF COUNTH = 1 and LBACK = "00000000"THEN LBACK <= "10000000"; END IF; IF (LBACK(0) = '1' AND BREQ(0) = '0') OR (LBACK(1) = '1' AND BREQ(1) = '0') OR (LBACK(2) = '1' AND BREQ(2) = '0') OR (LBACK(3) = '1' AND BREQ(3) = '0') OR (LBACK(4) = '1' AND BREQ(4) = '0') OR (LBACK(5) = '1' AND BREQ(5) = '0') OR (LBACK(6) = '1' AND BREQ(6) = '0') OR (LBACK(7) = '1' AND BREQ(7) = '0') THEN LBACK <= "00000000"; EN <= '1'; IF COUNT > 0 THEN COUNT := COUNT - 1; END IF; IF COUNTA > 0 THEN COUNTA := COUNTA - 1; END IF; IF COUNTB > 0 THEN COUNTB := COUNTB - 1; END IF; IF COUNTC > 0 THEN COUNTC := COUNTC - 1; END IF; IF COUNTD > 0 THEN COUNTD := COUNTD - 1; END IF; IF COUNTE > 0 THEN COUNTE := COUNTE - 1; END IF; IF COUNTF > 0 THEN COUNTF := COUNTF - 1; END IF; IF COUNTG > 0 THEN COUNTG := COUNTG - 1; END IF; IF COUNTH > 0 THEN COUNTH := COUNTH - 1; END IF; END IF; DELAY <= 0 ; INT <= '0'; LINT <= '0'; ELSIF EN = '1' THEN IF DELAY < 3 THEN LINT <= '1'; INT <= '1'; -- KEEP INT HIGH FOR 3 CLOCK CYCLES. DELAY <= DELAY + 1; ELSIF DELAY = 3 THEN INT <= '0'; LINT <= '0'; IF DONE = '1' THEN From the lower core when the acces to BUS is done. EN <= '0'; END IF; END IF; ELSIF COUNT = 0 THEN LBACK <= "00000000"; END IF; END IF; END PROCESS; Sumeet Suri Resi: 814-278-9272 Off: 814-865-9861 --------------------------------- |
|
|
|
Well .. this is the first step in understanding Simulatable code vs Synthesizeable code. VHDL provides a lot of constructs that will simulate correctly but have no hardware instantiation. You're using integer concepts like '>' and '<' and expecting them to map correctly into hardware. VHDL is a hardware DESCRIPTION language, not a high level programming language. Whenever you write in VHDL, you should have in mind the hardware (gates) that you expect your design to synthesize to. PCI's arbitration scheme DOES allow for some priority, but it greatly complicates the arbitration. Most arbitration schemes are round-robin to ensure equal opportunity to access to the bus. The arbiter that you wrote appears to queue up request cycles. That's not how any bus I've ever seen works. Normally, a device requiring the bus will assert a request line. This line will remain asserted until the device no longer needs the bus. When the device is given the grant line, it takes the bus and begins its transfers. Depending on how the arbiter is implemented, you can remove the grant based on certain rules (PCI) or you can take away the grant based on a maximum number of cycles (latency timeout) or you can trust that the device won't tie up the bus and let the grant go away when the request goes away. Take some time and work out in gates and synthesizeable blocks what exactly you think your arbiter should look like. Something else you should ask yourself .. do you REALLY need 8 bus masters? Keith On Tue, 16 Apr 2002, Sumeet Suri wrote: > HI guys, > I am looking to implement a Bus Arbiter in VHdl for my design. Right now > I have just 8 hosts (or devices) who request access for the Bus. > Each of them request for access and then get back an ACk when it is there > turn. Along with a priority arbitation I also need the arbiter to store all requests > that are made even when someone else is using the BUs. > I have written a Sequential code which works fine in simulation but when i try > to implement it in hardware(xess Virtex 800 at 25MHz.) it does NOT work. > I even tried to verify after implementation and yet it does not work. :( > Do u guys know of some better way of doing this. How does PCI or ISA fo something > like this. > This is the code that I wrote. Thought it shoudl work. let me know if u guys think i am doing > something wron. > Thanks > Sumeet > Code: > > PROCESS(CLK) > VARIABLE COUNT : INTEGER RANGE 0 TO 15; > VARIABLE COUNTA : INTEGER RANGE 0 TO 15; > VARIABLE COUNTB : INTEGER RANGE 0 TO 15; > VARIABLE COUNTC : INTEGER RANGE 0 TO 15; > VARIABLE COUNTD : INTEGER RANGE 0 TO 15; > VARIABLE COUNTE : INTEGER RANGE 0 TO 15; > VARIABLE COUNTF : INTEGER RANGE 0 TO 15; > VARIABLE COUNTG : INTEGER RANGE 0 TO 15; > VARIABLE COUNTH : INTEGER RANGE 0 TO 15; > BEGIN > IF CLK' EVENT AND CLK = '1' THEN > IF BREQ(0) = '1' THEN > IF COUNTA = 0 THEN > COUNT := COUNT + 1; > COUNTA := COUNT; > END IF; > END IF; > IF BREQ(1) = '1' THEN > IF COUNTB = 0 THEN > COUNT := COUNT + 1; > COUNTB := COUNT; > END IF; > END IF; > IF BREQ(2) = '1' THEN > IF COUNTC = 0 THEN > COUNT := COUNT + 1; > COUNTC := COUNT; > END IF; > END IF; > IF BREQ(3) = '1' THEN > IF COUNTD = 0 THEN > COUNT := COUNT + 1; > COUNTD := COUNT; > END IF; > END IF; > IF BREQ(4) = '1' THEN > IF COUNTE = 0 THEN > COUNT := COUNT + 1; > COUNTE := COUNT; > END IF; > END IF; > IF BREQ(5) = '1' THEN > IF COUNTF = 0 THEN > COUNT := COUNT + 1; > COUNTF := COUNT; > END IF; > END IF; > IF BREQ(6) = '1' THEN > IF COUNTG = 0 THEN > COUNT := COUNT + 1; > COUNTG := COUNT; > END IF; > END IF; > IF BREQ(7) = '1' THEN > IF COUNTH = 0 THEN > COUNT := COUNT + 1; > COUNTH := COUNT; > END IF; > END IF; > > IF EN = '0' and COUNT >= 1 THEN > IF COUNTA = 1 and LBACK = "00000000" THEN > LBACK <= "00000001"; > ELSIF COUNTB = 1 and LBACK = "00000000"THEN > LBACK <= "00000010"; > ELSIF COUNTC = 1 and LBACK = "00000000"THEN > LBACK <= "00000100"; > ELSIF COUNTD = 1 and LBACK = "00000000"THEN > LBACK <= "00001000"; > ELSIF COUNTE = 1 and LBACK = "00000000"THEN > LBACK <= "00010000"; > ELSIF COUNTF = 1 and LBACK = "00000000"THEN > LBACK <= "00100000"; > ELSIF COUNTG = 1 and LBACK = "00000000"THEN > LBACK <= "01000000"; > ELSIF COUNTH = 1 and LBACK = "00000000"THEN > LBACK <= "10000000"; > END IF; > > IF (LBACK(0) = '1' AND BREQ(0) = '0') OR > (LBACK(1) = '1' AND BREQ(1) = '0') OR > (LBACK(2) = '1' AND BREQ(2) = '0') OR > (LBACK(3) = '1' AND BREQ(3) = '0') OR > (LBACK(4) = '1' AND BREQ(4) = '0') OR > (LBACK(5) = '1' AND BREQ(5) = '0') OR > (LBACK(6) = '1' AND BREQ(6) = '0') OR > (LBACK(7) = '1' AND BREQ(7) = '0') THEN > > LBACK <= "00000000"; > EN <= '1'; > > IF COUNT > 0 THEN > COUNT := COUNT - 1; > END IF; > IF COUNTA > 0 THEN > COUNTA := COUNTA - 1; > END IF; > IF COUNTB > 0 THEN > COUNTB := COUNTB - 1; > END IF; > IF COUNTC > 0 THEN > COUNTC := COUNTC - 1; > END IF; > IF COUNTD > 0 THEN > COUNTD := COUNTD - 1; > END IF; > IF COUNTE > 0 THEN > COUNTE := COUNTE - 1; > END IF; > IF COUNTF > 0 THEN > COUNTF := COUNTF - 1; > END IF; > IF COUNTG > 0 THEN > COUNTG := COUNTG - 1; > END IF; > IF COUNTH > 0 THEN > COUNTH := COUNTH - 1; > END IF; > > END IF; > > DELAY <= 0 ; > INT <= '0'; > LINT <= '0'; > ELSIF EN = '1' THEN > > IF DELAY < 3 THEN > LINT <= '1'; > INT <= '1'; -- KEEP INT HIGH FOR 3 CLOCK CYCLES. > DELAY <= DELAY + 1; > ELSIF DELAY = 3 THEN > INT <= '0'; > LINT <= '0'; > IF DONE = '1' THEN From the lower core when the acces to BUS is done. > EN <= '0'; > END IF; > END IF; > ELSIF COUNT = 0 THEN > LBACK <= "00000000"; > END IF; > END IF; > END PROCESS; > Sumeet Suri > Resi: 814-278-9272 Off: 814-865-9861 > --------------------------------- > > To post a message, send it to: > To unsubscribe, send a blank message to: -- Keith D. Shapiro http://www.torilive.org/ |
|
|
|
Hi Keith, Thanks for your opinion. But here is what I have to say. What i am doing here is Multi-tasking between different applications. They are all trying to acess the same shared resources. --VHDL provides a lot of constructs that will simulate correctly but have no --hardware instantiation. You're using integer concepts like '>' and '<' --and expecting them to map correctly into hardware. I would have expected the my synthesis tool to convert my constructs to represent them in hardware. I can easily replace statments like count > 0 with (if (count and "0000") = '1' ) --PCI's arbitration scheme DOES allow for some priority, but it greatly --complicates the arbitration. Most arbitration schemes are round-robin to --ensure equal opportunity to access to the bus. --The arbiter that you wrote appears to queue up request cycles. That's not --how any bus I've ever seen works. Normally, a device requiring the bus --will assert a request line. This line will remain asserted until the --device no longer needs the bus. When the device is given the grant line, --it takes the bus and begins its transfers. Depending on how the arbiter --is implemented, you can remove the grant based on certain rules (PCI) or --you can take away the grant based on a maximum number of cycles (latency --timeout) or you can trust that the device won't tie up the bus and let the --grant go away when the request goes away. Here i am still doing the same thing. the application requests for the access and if there is not one in the queue then he is given access. or else he too is put in the queue(FIFO) and then when its his turn, he is given access. once a application is given access, it is given the grant line until the application lowers its request line. Thus the Arbiter does NOT need to know the latency or any policy for how long the device will have access. --Take some time and work out in gates and synthesizeable blocks what --exactly you think your arbiter should look like. --Something else you should ask yourself .. do you REALLY need 8 bus --masters? Yes !! actually would be much happier if I could fo something like 32 or 64 or even more. :):) But I am not sure how feasible it is. like I said, its not actually BUS masters. its like different application. so more the merrier. Maybe I need to think of a different way of doing it. Thanks again .. Regards Sumeet Keith On Tue, 16 Apr 2002, Sumeet Suri wrote: > HI guys, > I am looking to implement a Bus Arbiter in VHdl for my design. Right now > I have just 8 hosts (or devices) who request access for the Bus. > Each of them request for access and then get back an ACk when it is there > turn. Along with a priority arbitation I also need the arbiter to store all requests > that are made even when someone else is using the BUs. > I have written a Sequential code which works fine in simulation but when i try > to implement it in hardware(xess Virtex 800 at 25MHz.) it does NOT work. > I even tried to verify after implementation and yet it does not work. :( > Do u guys know of some better way of doing this. How does PCI or ISA fo something > like this. > This is the code that I wrote. Thought it shoudl work. let me know if u guys think i am doing > something wron. > Thanks > Sumeet > Code: > > PROCESS(CLK) > VARIABLE COUNT : INTEGER RANGE 0 TO 15; > VARIABLE COUNTA : INTEGER RANGE 0 TO 15; > VARIABLE COUNTB : INTEGER RANGE 0 TO 15; > VARIABLE COUNTC : INTEGER RANGE 0 TO 15; > VARIABLE COUNTD : INTEGER RANGE 0 TO 15; > VARIABLE COUNTE : INTEGER RANGE 0 TO 15; > VARIABLE COUNTF : INTEGER RANGE 0 TO 15; > VARIABLE COUNTG : INTEGER RANGE 0 TO 15; > VARIABLE COUNTH : INTEGER RANGE 0 TO 15; > BEGIN > IF CLK' EVENT AND CLK = '1' THEN > IF BREQ(0) = '1' THEN > IF COUNTA = 0 THEN > COUNT := COUNT + 1; > COUNTA := COUNT; > END IF; > END IF; > IF BREQ(1) = '1' THEN > IF COUNTB = 0 THEN > COUNT := COUNT + 1; > COUNTB := COUNT; > END IF; > END IF; > IF BREQ(2) = '1' THEN > IF COUNTC = 0 THEN > COUNT := COUNT + 1; > COUNTC := COUNT; > END IF; > END IF; > IF BREQ(3) = '1' THEN > IF COUNTD = 0 THEN > COUNT := COUNT + 1; > COUNTD := COUNT; > END IF; > END IF; > IF BREQ(4) = '1' THEN > IF COUNTE = 0 THEN > COUNT := COUNT + 1; > COUNTE := COUNT; > END IF; > END IF; > IF BREQ(5) = '1' THEN > IF COUNTF = 0 THEN > COUNT := COUNT + 1; > COUNTF := COUNT; > END IF; > END IF; > IF BREQ(6) = '1' THEN > IF COUNTG = 0 THEN > COUNT := COUNT + 1; > COUNTG := COUNT; > END IF; > END IF; > IF BREQ(7) = '1' THEN > IF COUNTH = 0 THEN > COUNT := COUNT + 1; > COUNTH := COUNT; > END IF; > END IF; > > IF EN = '0' and COUNT >= 1 THEN > IF COUNTA = 1 and LBACK = "00000000" THEN > LBACK <= "00000001"; > ELSIF COUNTB = 1 and LBACK = "00000000"THEN > LBACK <= "00000010"; > ELSIF COUNTC = 1 and LBACK = "00000000"THEN > LBACK <= "00000100"; > ELSIF COUNTD = 1 and LBACK = "00000000"THEN > LBACK <= "00001000"; > ELSIF COUNTE = 1 and LBACK = "00000000"THEN > LBACK <= "00010000"; > ELSIF COUNTF = 1 and LBACK = "00000000"THEN > LBACK <= "00100000"; > ELSIF COUNTG = 1 and LBACK = "00000000"THEN > LBACK <= "01000000"; > ELSIF COUNTH = 1 and LBACK = "00000000"THEN > LBACK <= "10000000"; > END IF; > > IF (LBACK(0) = '1' AND BREQ(0) = '0') OR > (LBACK(1) = '1' AND BREQ(1) = '0') OR > (LBACK(2) = '1' AND BREQ(2) = '0') OR > (LBACK(3) = '1' AND BREQ(3) = '0') OR > (LBACK(4) = '1' AND BREQ(4) = '0') OR > (LBACK(5) = '1' AND BREQ(5) = '0') OR > (LBACK(6) = '1' AND BREQ(6) = '0') OR > (LBACK(7) = '1' AND BREQ(7) = '0') THEN > > LBACK <= "00000000"; > EN <= '1'; > > IF COUNT > 0 THEN > COUNT := COUNT - 1; > END IF; > IF COUNTA > 0 THEN > COUNTA := COUNTA - 1; > END IF; > IF COUNTB > 0 THEN > COUNTB := COUNTB - 1; > END IF; > IF COUNTC > 0 THEN > COUNTC := COUNTC - 1; > END IF; > IF COUNTD > 0 THEN > COUNTD := COUNTD - 1; > END IF; > IF COUNTE > 0 THEN > COUNTE := COUNTE - 1; > END IF; > IF COUNTF > 0 THEN > COUNTF := COUNTF - 1; > END IF; > IF COUNTG > 0 THEN > COUNTG := COUNTG - 1; > END IF; > IF COUNTH > 0 THEN > COUNTH := COUNTH - 1; > END IF; > > END IF; > > DELAY <= 0 ; > INT <= '0'; > LINT <= '0'; > ELSIF EN = '1' THEN > > IF DELAY < 3 THEN > LINT <= '1'; > INT <= '1'; -- KEEP INT HIGH FOR 3 CLOCK CYCLES. > DELAY <= DELAY + 1; > ELSIF DELAY = 3 THEN > INT <= '0'; > LINT <= '0'; > IF DONE = '1' THEN From the lower core when the acces to BUS is done. > EN <= '0'; > END IF; > END IF; > ELSIF COUNT = 0 THEN > LBACK <= "00000000"; > END IF; > END IF; > END PROCESS; > Sumeet Suri > Resi: 814-278-9272 Off: 814-865-9861 > --------------------------------- > > To post a message, send it to: > To unsubscribe, send a blank message to: -- Keith D. Shapiro http://www.torilive.org/ To post a message, send it to: To unsubscribe, send a blank message to: Sumeet Suri Resi: 814-278-9272 Off: 814-865-9861 --------------------------------- |
|
|
|
> Here i am still doing the same thing. the application requests for the > access and if there is not one in the queue then he is given access. > or else he too is put in the queue(FIFO) and then when its his turn, > he is given access. I think Keith's point is that your queuing is far too complex, if you can live with fairness rather than strict FIFO ordering. A typical fair arbiter uses priority, but it rotates the priority so that the last master that was granted the bus becomes the lowest priority for the next cycle. Example, for four hosts named A through D, where priority 1 is the highest priority: arb priority requests cycle A B C D A B C D grant ----- ------------- ------------- ----- 1 1 2 3 4 * * A 2 4 1 2 3 * * * B 3 3 4 1 2 * * * C 4 2 3 4 1 * * D 5 1 2 3 4 * * A 6 4 1 2 3 * * B Note that D requested the bus in arb cycle 1, before B requested it in arb cycle 2, but that B received the grant first due to the rotating priority scheme. Thus the grants don't occur in the strict order of requests, but the average request to grant delay will be the same for each master. This is simpler to implement in hardware than strict FIFO queuing. Some bus protocols have a mechanism for relinquishing the bus that is independent of the bus request. In such a system, a master can relinquish the bus but keep its bus request asserted. If there is a rotating priority, that master will get the bus again after all other masters requesting it have gotten their grants (assuming that the other masters don't deassert their requests before they are granted). |
|
|
|
I just noticed that after editing my rotating priority arbitration example, the priorities and grants happened to go around in order. That was purely by accident and might confuse someone as to how the priorities are assigned. Here's another example: arb priority requests cycle A B C D A B C D grant ----- ------------- ------------- ----- 1 1 2 3 4 * * A 2 4 1 2 3 * * C 3 2 3 4 1 * * D 5 1 2 3 4 * * B 6 3 4 1 2 * * C |