![]() |
|
|
|||||||
![]() |
VHDL - generic serial to parallel IO module |
|
|
Thread Tools | Search this Thread |
|
|
#1 |
|
Hi Group,
I'm trying to find a way to input and output multiple m bit signals from an FPGA, where m is a very large number. The design is a (not quite) serial to parallel in and a parallel to serial out module. let's say that input is a 32 bit wide signal, inputOne is a 256 bit wide signal. inputCounter counts from 0 to 7, inputNumber counts from 0 to 3. inputCounter counts if input is enabled. inputNumber counts if inputCounter reaches 7 and input is enabled. My question is whether I can provide a generate statement or synthesisable function to provide the following: arbitrary numbers of input/output groups, with an arbitrary serial width, and an arbitrary parallel width. I'd like to drive logic creation with the following numbers: width of parallel bus, width of 'serial' bus, number of inputs, number of outputs, number of input serial 'slices' number of output serial 'slices' number of bits for inputNumber, inputGroup, outputNumber, outputGroup counters Is there a way of writing inputOne( variable1 downto variable2 ) <= input ? Can I find a way to produce the following in some kind of code generating loop? Are there guidelines for writing synthesisable functions, or is this vendor specific in the main? thanks Edward Watts PS Currently my code looks something like: process( clk ) --reset code here if clk'event and clk = '1' then if some_IO_condition = '1' then -- do stuff elsif inputing = '1' then if inputNumber = "00" then if inputCounter = "000" then inputOne( 31 downto 0 ) <= input; elsif inputCounter = "001" then inputOne( 63 downto 32 ) <= input; --... elsif inputCounter = "111" then inputOne( 255 downto 224 ) <= input; end if; elsif inputNumber = "01" then if inputCounter = "000" then inputTwo( 31 downto 0 ) <= input; elsif inputCounter = "001" then --... end if; elsif inputGroup = "10" then --... elsif inputGroup = "11" then --... end if; elsif outputting = '1' then if outputNumber = "00" then if outputCounter = "000" then output_internal <= output( 31 downto 0 ); elsif outputCounter = "001" then --... end if; end if; end if; end if; end process; eddie |
|
|
|
|
#2 |
|
Posts: n/a
|
eddie wrote:
> Hi Group, > > ... > My question is whether I can provide a generate statement or > synthesisable function to provide the following: arbitrary numbers of > input/output groups, with an arbitrary serial width, and an arbitrary > parallel width. > I'd like to drive logic creation with the following numbers: > width of parallel bus, > width of 'serial' bus, > number of inputs, > number of outputs, > number of input serial 'slices' > number of output serial 'slices' > number of bits for inputNumber, inputGroup, outputNumber, outputGroup > counters > > > Is there a way of writing inputOne( variable1 downto variable2 ) <= > input ? > Can I find a way to produce the following in some kind of code > generating loop? > Are there guidelines for writing synthesisable functions, or is this > vendor specific in the main? > If your arbitrary numbers are generics, that is, they are fixed at synthesis time, then generate statements are perfect for what you describe. For example, create a generic loop for the number of input slices: slice_g: for i in 0 to slices-1 generate slice_p: process(...) begin inputOne(width*(i+1)-1 downto width*i) <= whatever; > ... > if inputNumber = "00" then > > if inputCounter = "000" then > inputOne( 31 downto 0 ) <= input; > > elsif inputCounter = "001" then > inputOne( 63 downto 32 ) <= input; > > --... > elsif inputCounter = "111" then > inputOne( 255 downto 224 ) <= input; > > end if; > > elsif inputNumber = "01" then > > if inputCounter = "000" then > inputTwo( 31 downto 0 ) <= input; > elsif inputCounter = "001" then > --... > end if; Strictly speaking, this really isn't an 'elsif inputNumber', since for example the signal inputOne is only altered in one case. That is, an if...elsif... implements a priority encoding. But in your situation, there is no priority. So it really should be if inputNumber = "00" then ... end if; if inputNumber = "01" then ... end if; On the other hand, I suspect the synthesis tools will automatically simplify this correctly, so it is probably just an issue of writing the code in a way that clearly describes what is happening. Duane Clark |
|
|
|
#3 |
|
Posts: n/a
|
eddie wrote:
> My question is whether I can provide a generate statement or > synthesisable function to provide the following: arbitrary numbers of > input/output groups, with an arbitrary serial width, and an arbitrary > parallel width. Synthesizable *process*, yes. You can generate processes as Duane outlined or declare complex register structures in a single process. > Is there a way of writing inputOne( variable1 downto variable2 ) <= > input ? Not exactly, but I can declare internal register structures of arbitrary complexity using generic or packaged constants for dimensions. For example: -- Make and init 6 sets of 32 bit counter/register pairs process (sys_clk, reset) is -- 32 bit register subtype stat_reg_t is unsigned (cnt_len-1 downto 0); -- counter/reg pair type cnt_reg_t is array(1 to 2) of stat_reg_t; -- each of 6 kinds gets a counter/reg type cnt_t is array(enumeration_t) of cnt_reg_t; -- signle reg value constant stat_reg_clr : stat_reg_t := (stat_reg_t'range => '0'); -- two regs value constant stat_cnt_clr : cnt_reg_t := (cnt_reg_t'range => stat_reg_clr); -- all regs value constant cnt_clr : cnt_t := (cnt_t'range => stat_cnt_clr); -- all regs instance variable cnt : cnt_t; Then after the BEGIN I can use and update these variables inside the process to infer the whole truckload of gates and flops. > Are there guidelines for writing synthesisable functions, or is this > vendor specific in the main? A function is not a synthesizable unit by itself, but I use them all the time in synthesizable design entities to update register values. I haven't written up any synthesis guidelines, but you can infer some from reference design here: http://home.comcast.net/~mike_treseler/ Counters, shifters, controllers, rom and ram can all be inferred from generic vhdl code. PLL stuff is device specific, and can be black-boxed using an unbound component instance in the vhdl source. -- Mike Treseler Mike Treseler |
|
|
|
#4 |
|
Posts: n/a
|
Thanks for the help.
I assume the way to select which input is going to be used is to do something like: input_g : for j in 0 to numInputs-1 generate slice_g : for i in 0 to slices-1 generate slice_p : process(...) begin ( inputs(j) )( width * (i+1) - 1 downto width*i ) <= lines; But I'm unsure whether or not that is the correct way to handle multidimensional arrays in VHDL. I'll have a look at this. Can you comment on this as an approach please? eddie |
|
|
|
#5 |
|
Posts: n/a
|
eddie wrote:
> Thanks for the help. > I assume the way to select which input is going to be used is to do > something like: > input_g : for j in 0 to numInputs-1 generate > slice_g : for i in 0 to slices-1 generate > slice_p : process(...) > begin > ( inputs(j) )( width * (i+1) - 1 downto width*i ) <= lines; > > But I'm unsure whether or not that is the correct way to handle > multidimensional arrays in VHDL. I'll have a look at this. Can you > comment on this as an approach please? > I don't use multidimensional arrays enough to know off the top of my head. But yes, it should be something like that. Duane Clark |
|
![]() |
| Thread Tools | Search this Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| New releases: Game Plan, Daddy Day Camp & Curb Your Enthusiasm: Updated complete R1 DVD DB & info lists | Doug MacLean | DVD Video | 0 | 11-13-2007 09:52 PM |
| => Professional Software CAD CAM CFD GIS ! FTP-Download! | UnlockSofts | General Help Related Topics | 2 | 07-17-2007 11:44 AM |
| Altera Soft Core parallel tasking? Possible | bbiandov | Hardware | 0 | 12-02-2006 06:00 AM |
| DVD Verdict reviews: PARANOIA AGENT: SERIAL PSYCHOSIS and more! | DVD Verdict | DVD Video | 0 | 04-28-2005 09:10 AM |