FPGARelated.com
Forums

BPSK modulation on Xilinx FPGA

Started by Ben Marpe ●February 1, 2006
Hi everybody,

I'm trying to implement a BPSK modulation.
A sin waveform has to be generated at a given frequency (1MHz) with
phase offset (binary PSK i.e. 180=B0) when transition occures on a data
wire.

Is there any "simple" LogiCORE with BPSK functionality available for my
Xilinx Spartan-3 - Board ?

My attempt would be a LUT in BRAM - but do I have to fill its content
manualy ? The LUT content (e.g. 16bit) could drive a DAC.

On the other hand, If I'm forced to use a external DAC, I might use a
DDS (e.g. AD9834) with all BPSK functionality on chip...  ?!?

I'm interested in your ideas and suggestions !

Bye, BEN

Ben Marpe wrote:

> My attempt would be a LUT in BRAM - but do I have to fill its content > manualy ? The LUT content (e.g. 16bit) could drive a DAC.
There's probably some other way to do it, but I'd just write a quick program in C or whatver that generates the table in a format compatible with your HDL or BRAM initializer. Xilinx has a tool which takes a while to figure out but lets you insert such data into the already generated bitstream - used it a lot to change the program of a soft core processor without rebuilding the design. One thing that can be a bit of a pain is getting the data to be there in both simulation and in the bitsream - often you have to put it in twice. If the table isn't very big, encoding it in the HDL might be simplest?
Ben Marpe wrote:

> Hi everybody, > > I'm trying to implement a BPSK modulation. > A sin waveform has to be generated at a given frequency (1MHz) with > phase offset (binary PSK i.e. 180�) when transition occures on a data > wire. > > Is there any "simple" LogiCORE with BPSK functionality available for my > Xilinx Spartan-3 - Board ? > > My attempt would be a LUT in BRAM - but do I have to fill its content > manualy ? The LUT content (e.g. 16bit) could drive a DAC. > > On the other hand, If I'm forced to use a external DAC, I might use a > DDS (e.g. AD9834) with all BPSK functionality on chip... ?!? > > I'm interested in your ideas and suggestions ! > > Bye, BEN >
Since your frequency is only 1 MHz, and assuming you have a clock source where you can get, say 80 Mhz, you can do the DAC as s sigma-delta DAC in the FPGA, then all you need outside the FPGA is a resistor and capacitor. A LUT implemented with block RAM should give you a pretty clean sine output. Perhaps the easiest way to fill the LUT (assuming you are using VHDL) is to use excel, matlab, or C to produce one cycle of sine sampled at your desired pahse resolution as a rounded integer y= round(2^bits * sin(2*pi*n/resolution)), then cut and paste that data into a constant integer array in your VHDL, then convert the integer to the bit vector needed by the BRAM INIT= attribute using a VHDL function. Alternatively, you could generate ascii binary in your external application and past that into an array of bit_vectors directly.
cs_posting@hotmail.com wrote:
> One thing that can be a bit of a pain is getting the data to be there > in both simulation and in the bitsream - often you have to put it in > twice. If the table isn't very big, encoding it in the HDL might be > simplest? >
Yes, that is a pain. The generics for simulation want a bitvector, while the attributes for passing to the PAR tools want hex strings. Rather than enter the tables twice in different formats (and possibly getting a simulation mismatch), I find it easier to use a VHDL function to do the conversion of the bit vector to HEX: function bv2hex (val:bit_vector) return string is type hex_lut is array (0 to 15) of character; constant hextable:hex_lut := ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); constant str_len:natural:=(val'length+3)/4; variable temp:integer; variable ret_string: string(str_len downto 1); begin temp:=0; for j in 0 to val'length-1 loop if val(j)='1' then temp:=temp + 2**(j mod 4); end if; if (j mod 4)=3 or j=val'length-1 then ret_string(j/4+1):= hextable(temp); temp:=0; end if; end loop; return ret_string; end bv2hex;
Ray, one thought -
I recently had to modify my romgen program (www.fpgaarcade.com) which 
produces init strings and generics with a conversion function much as you 
suggest.
However the Synplicity tool uses a different attribute style to Mentor's 
Precision. I discovered that Synplicity at least will produce the correct 
block ram init strings with only the generic set - no synthesis attributes 
required.

About time too ....
/Mike

"Ray Andraka" <ray@andraka.com> wrote in message 
news:gn4Ef.33686$bF.17923@dukeread07...
> cs_posting@hotmail.com wrote: >> One thing that can be a bit of a pain is getting the data to be there >> in both simulation and in the bitsream - often you have to put it in >> twice. If the table isn't very big, encoding it in the HDL might be >> simplest? >> > > Yes, that is a pain. The generics for simulation want a bitvector, while > the attributes for passing to the PAR tools want hex strings. Rather than > enter the tables twice in different formats (and possibly getting a > simulation mismatch), I find it easier to use a VHDL function to do the > conversion of the bit vector to HEX: > > function bv2hex (val:bit_vector) return string is > type hex_lut is array (0 to 15) of character; > constant hextable:hex_lut := > ('0', '1', '2', '3', '4', '5', '6', '7', > '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); constant > str_len:natural:=(val'length+3)/4; > variable temp:integer; > variable ret_string: string(str_len downto 1); > begin temp:=0; for j in 0 to val'length-1 loop if val(j)='1' then > temp:=temp + 2**(j mod 4); > end if; > if (j mod 4)=3 or j=val'length-1 then > ret_string(j/4+1):= hextable(temp); > temp:=0; > end if; > end loop; > return ret_string; > end bv2hex;
Ray Andraka wrote:

> Alternatively, you could generate ascii binary in your external > application and past that into an array of bit_vectors directly.
This is where I like verilog's include directive... no pasting required.
MikeJ wrote:
> Ray, one thought - > I recently had to modify my romgen program (www.fpgaarcade.com) which > produces init strings and generics with a conversion function much as you > suggest. > However the Synplicity tool uses a different attribute style to Mentor's > Precision. I discovered that Synplicity at least will produce the correct > block ram init strings with only the generic set - no synthesis attributes > required. > > About time too .... > /Mike >
Mike, Yes, it is true if you use the synplify and mentor attributes. Instead, you can set them up as user attributes using the Xilinx attribute name (INIT_XX=) so that it is tool agnostic. That indifference to which tool it is used on is also why I haven't been taking advantage of Synplicity's (pretty much still unique) ability to infer the attributes from the generics.
Ben,

    I used a DDS LogiCORE to generate the sine (and cosine) and then a pair 
of two-complementor LogiCORE to handle the BPSK; you wire the data value to 
the BYPASS pin. Works like a champ.

Marty

martin dot ryba (at) verizon dot net

"Ben Marpe" <Ben.Marpe@gmx.de> wrote in message 
news:1138801274.996807.307800@g49g2000cwa.googlegroups.com...
Hi everybody,

I'm trying to implement a BPSK modulation.
A sin waveform has to be generated at a given frequency (1MHz) with
phase offset (binary PSK i.e. 180&#4294967295;) when transition occures on a data
wire.

Is there any "simple" LogiCORE with BPSK functionality available for my
Xilinx Spartan-3 - Board ?

My attempt would be a LUT in BRAM - but do I have to fill its content
manualy ? The LUT content (e.g. 16bit) could drive a DAC.

On the other hand, If I'm forced to use a external DAC, I might use a
DDS (e.g. AD9834) with all BPSK functionality on chip...  ?!?

I'm interested in your ideas and suggestions !

Bye, BEN


On 1 Feb 2006 14:30:14 -0800, cs_posting@hotmail.com wrote:

>Ray Andraka wrote: > >> Alternatively, you could generate ascii binary in your external >> application and past that into an array of bit_vectors directly. > >This is where I like verilog's include directive... no pasting >required.
... until you need two instances of the same module with different INIT values. You can't (for example) have a parameter select different INIT values. `include happens at compile time. Deferring this until elaboration time would be much more useful (for some applications). YMMV. Regards, Allan
Allan Herriman wrote:

> > ... until you need two instances of the same module with different > INIT values. You can't (for example) have a parameter select > different INIT values. > > `include happens at compile time. Deferring this until elaboration > time would be much more useful (for some applications). > YMMV. > > Regards, > Allan
That's an advantage of VHDL. I regularly put the parameters into a generic as an integer array so that I can have multiple instances of the same component with different init data. Doing that in verilog requires a pre-processor to parse out those and rewrite it into inline instances with different names. Kind of awkward if you ask me. If you don't want to paste, you can always write your other application so that it writes out a complete file containing a VHDL package that has the constants declared in it. Then you just need to include that package in a library statement at the top of your VHDL code. This is handy if you have something that is going to get updated often enough that pasting in presents too great an opportunity of screwing it up. Also good for throwing code over a wall.