- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hi.. i'm a beginner and currently working on qpsk modem using cyclone II, . I'm really need vhdl code for qpsk modulator and demodulator. I will use it and implement into fpga. Any help on it are most welcome.Plezz..
Link Copied
10 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Have you tried a search in altera/xilinx site or google(free core). You can write for a simple qpsk by having some binary stream then map every pair into one symbol(i.e. pick up pairs sequentially and allocate to each a signal value.You will need two channels of this signal(call them I,Q) Mapping is arbitrary (though predetermined for certain schemes) e.g. you can map as follows(for 8 bits): 00 => I=127,Q=127 01 => I=127,Q=-127 10=> I=-127,-127 11=> I=-127,127 After mapping, you need to shape the pulses, a common filter used is rrcos(root raised cosine in comms, or gaussian in mobile industry). After shaping you need to pass the signals I,Q to a carrier(upconversion). This is done in a complex multiplier that takes in I/Q and sin/cos of your chosen carrier frequency. Next you convert the upconverted symbols to analogue(some DACs do the above complex mult as well), if DAC's input speed is more than symbol rate(and this is common)then you need to upsampe the symbols i.e. use interpolation to lift up your signal to DAC speed. So, there is a lot of learning here. The domodulator is more difficult and has to filter noise,lock to carrier then to clock then reverse the mapping. kaz- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hi..thanx for your quick responds. I'm just wondering.. is there any example of vhdl code for qpsk modem?? i've made some search before on this topic and i have found lots of theory. But i really have no idea how to write it in vhdl since i'm only the beginner and still study about it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
First, use a language that you know well to simulate your QPSK modem in floating point.
Move from that point into a fixed point domain (simulating the ADC with fixed dynamic range, etc). From there, partition the design into independent blocks. Finally, write those blocks into Verilog or VHDL. At the end, you should have a good synthesizable modem!- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
www.opencores.org have plenty of cores. I haven't used them but may be useful source for some of us. I know they got ofdm modulator but not sure about basic qpsk. kaz- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
sir..
i've been able to create vhdl code for each block in qpsk modulator part. But, there are 1 block that have an error. it is for unipolar to bipolar.. i need to the incoming data for both I-channel and Q-channel which consist of logic 1 or logic 0. i want to change logic 1 to 1 and logic 0 to -1. here are the code that i have write for unipolar to bipolar converter. ----------------UNIPOLAR TO BIPOLAR---------------[LOGIC 0=-1, LOGIC 1=1]------- LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; USE ieee.numeric_std.all; ------------------defines two types: unsigned and signed ENTITY unipolar_bipolar IS PORT( in_i,in_q : IN std_logic_vector (3 downto 0); -------4 bit------- bI,bQ: OUT std_logic_vector (3 downto 0) -------4 bit------- ); END unipolar_bipolar ; ARCHITECTURE beh OF unipolar_bipolar IS signal p: integer;------------out signal k: integer;-------------in signal n: std_logic_vector(3 downto 0);--------------out(final) signal i:integer; -----------------------for loop 0 until 3 (4 bit)----------- begin for i=> '0'; LOOP i=n; when in_i(n)=> k & in_q(n)=> k then case k is when k ='0' then -----must invert to signed value---[-1] p <= '1'; -------in std_logic out_q(n)<= conv_integer(p); out_i(n) <= conv_integer(p); --------convert into integer(signed) end case; case k is when k ='1' then-----must invert to unsigned value--[1] p <= '1'; -------in std_logic out_q(n)<= conv_integer('0'& p); out_i(n) <= conv_integer('0' & p); --------convert into integer(unsigned) end case; n = i+1; when n='3' loop; end LOOP; end beh; hope you can help me as soon as possible.. thank you so much..- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I am afraid I don't see anything correct or synthesizable in your code. It is much simpler than that. If your data is a serial bit stream then you need to convert every two bits(every pair) into signed I and Q straightaway: First convert your stream from 1 bit serial to two bit parallel then use a basic construct to output I/Q(mapping): assuming you converted your one bit data to the two bit sub_data then: case sub_data is .........when "00" => ...................... I <= std_logic_vector(to_signed(32767,16)); ......................Q <= std_logic_vector(to_signed(32767,16)); .........when "01" => ...................... I <= std_logic_vector(to_signed(32767,16)); ......................Q <= std_logic_vector(to_signed(-32767,16)); .........when "10" => ...................... I <= std_logic_vector(to_signed(-32767,16)); ...................... <= std_logic_vector(to_signed(32767,16)); .........when "11" => ...................... I <= std_logic_vector(to_signed(-32767,16)); ......................Q <= std_logic_vector(to_signed(-32767,16)); end case; notice that I/Q are 16 bits each ready for DAC, use whatever resolution you want for your DAC. The maximum level of 32767 may be too high and you can go lower if you want. so in short think of serial-parallel converter module followed by mapping module(or do both in one module) Your serial-to-parallel is a bit more difficult than the mapper. The output pairs must be at half speed of the input data stream and you should pair-up correctly(it is quite easy but many experienced designers could go wrong on pairing boundaries) You better try it first then if you come up with more code like the one you posted you should get some help before your compiler loses patience.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hi sir..
thank you for your quick reply. i want to ask you about how to convert std_logic_vector to signed and unsigned... let say.. when input => '1' then output <= ---------?? (unsigned) what are the syntax that can be used to convert to unsigned.. and when input => '0' then output <= ---------?? (signed) what are the syntax that can be used to convert to signed.. and what are the library that need to be used.. is it use ieee.std_logic_unsigned and use ieee.std_logic_signed or is it enough to just use ieee.numeric_std.all?? hope to hear from you soon.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Your wording indicates some unclear thoughts. You only need signed thinking. You got nothing to do with unsigned. The value 32767 means +32767 and doesn't mean unsigned. In each case of positive or negative values the MSB is used as sign bit(0 for +, 1 for -). We are talking here about 2's complement as is the case with most fpga signed computations. Check your DAC number system... Anyway for conversion between std_logic_vector and signed or unsigned try numeric_std library. std_logic <=> signed, std_logic <=> unsigned just use direct cast e.g. d_signed <= signed(data); -- data is std_logic_vector d_unsigned <= unsigned(data); -- data is std_logic_vector d_std_logic <= std_logic_vector(data); -- data is signed d_std_logic <= std_logic_vector(data); -- data is unsigned for integer to signed/unsigned you need one stage conversion only,define bitwidth: I <= to_signed(32767,16); -- I being signed I <= to_unsigned(32767,16); -- I being unsigned for integer <=> std_logic_vector you need two stages(cast plus conversion, you need define bitwidth) I <= std_logic_vector(to_signed(32767,16)); -- 7FFF, 15 bits magnitude I <= std_logic_vector(to_signed(-32767,16)); -- 8001h, 15 bits magnitude I <= std_logic_vector(to_unsigned(32767,16)); -- 7FFF, 16 bits magnitude edit: some engineers feel that VHDL is too complicated and unfriendly at this type conversion and have raised concerns to ieee. There is certainly room for improvement and mercy.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
sir..
my dac is 8 bit. what i'm try to say is... my input is 8 bit which can be either logic 0 or 1. when the data is logic 1... the output that i want is 1... when the data is logic 0.. the output is -1.. so..i think.. first i need to declare that each output gonna be 1 but it is either unsigned(+ve number) or signed (-ve number)...to get the value of 1 or -1. if my input is in std_logic_vector.. how can i compare this by 1 bit (std_logic)??- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I already stated in plain language that:
--- Quote Start --- Your wording indicates some unclear thoughts. You only need signed thinking. --- Quote End --- You cannot think of signed/unsigned at the same time, it is not just terminology but two different number systems. Your DAC range is +127 and not +1. You cannot send symbols to a satellite using +1 levels, you need good power signal to get through. Some people talk about +1 in a symbolic(logic) sense. your input is 8 bits wide. You have to think of communications as one serial bit because you can't(normally) send parallel data buses in sky. so you convert it to serial stream one after the other(starting with MSB or LSB or anywhere you like as long as your receiver knows how to reconstruct your 8 bit values. So your tasks are: 1) convert 8 bit input to a serial one bit stream 2) convert every two successive bits into a set of IQ values steps 1 & 2 can be combined like this: at every input sample(valid clk) think: bit(7) and bit(6) as pair 1, bit(5)& bit(4) as pair 2, bit(3) &bit(2) as pair 3, bit(1) & bit(0) as pair 4. action:convert each above pair to IQ pair of values as below and send IQ pair 1,IQ pair 2, IQ pair 3, IQ pair 4 sequentially to DAC(now in the form of +127). your new mapping code can be like this case sub_data is .........when "00" => ...................... I <= std_logic_vector(to_signed(127,8)); ......................Q <= std_logic_vector(to_signed(127,8)); .........when "01" => ...................... I <= std_logic_vector(to_signed(127,8)); ......................Q <= std_logic_vector(to_signed(-127,8)); .........when "10" => ...................... I <= std_logic_vector(to_signed(-127,8)); ......................Q <= std_logic_vector(to_signed(127,8)); .........when "11" => ...................... I <= std_logic_vector(to_signed(-127,8)); ......................Q <= std_logic_vector(to_signed(-127,8)); end case; At the DAC output your analogue signal will hopefully swing full scale voltage and that is what some call +1 or as you call it bipolar. The RF engineer will then do the rest. He will map your voltage swings to phase swings. He will generate a really fast frequency e.g. 500MHz sinusoid.(RF engineers live on these sinusoids). He will change the phase of his sinusoid through 90 degrees for every change of your DAC swing. The final carrier will be sent to power amplifier and into the aerial......In practice he will be very angry if you don't smooth those sharp corners of your +127 symbols in the digital domain. He can shape them in his analogue domain but they don't do that anymore...
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