Author Topic: Reorder/multiplex bitstreams (FPGA needed?)  (Read 5868 times)

0 Members and 1 Guest are viewing this topic.

Offline stefan_oTopic starter

  • Regular Contributor
  • *
  • Posts: 85
  • Country: de
Reorder/multiplex bitstreams (FPGA needed?)
« on: May 17, 2017, 06:59:16 pm »
Hey,
I would like to rearrange data to be able to connect two devices, unfortunately the data format is not compatible, I need a device for conversion

Code: [Select]
Input:
continuous clock
Data A (just raw bitsteam)
Data B (just raw bitsteam)
Code: [Select]
Output:
continuous clock (Input clock x2)
Data output as dwords: AAAAAAAA AAAAAAAA AAAAAAAA AAAAAAAA BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB AAAAA...
A/B output (low/high): LLLLLLLL LLLLLLLL LLLLLLLL LLLLLLLH HHHHHHHH HHHHHHHH HHHHHHHH HHHHHHHL LLLLL...
The maximum input clock is about 7 MHz.

What is simplest way two implement that? An µC like AVR is much too slow I assume, what kind of programmable logic device would you recommend? I assume there is no part that does this out of the box.

In case you're wondering: I would like to get DSD data from an ADC into an I2S input.

Best regards
Stefan
 

Online helius

  • Super Contributor
  • ***
  • Posts: 3642
  • Country: us
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #1 on: May 17, 2017, 07:53:10 pm »
You need a PLL to multiply the clock. For the A/B you need 4 32-bit FIFOs. A 74LS224 might work.
You could also use small PLDs if you need to minimize space. The Lattice iCE40 should be capable, I think.
 

Offline danadak

  • Super Contributor
  • ***
  • Posts: 1875
  • Country: us
  • Reactor Operator SSN-583, Retired EE
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #2 on: May 17, 2017, 09:37:31 pm »
Possibly a PSOC solution -


http://www.cypress.com/documentation/application-notes/an82250-psoc-3-psoc-4-and-psoc-5lp-implementing-programmable-logic


Written in Verilog and/or schematic capture solution......



Regards, Dana.
Love Cypress PSOC, ATTiny, Bit Slice, OpAmps, Oscilloscopes, and Analog Gurus like Pease, Miller, Widlar, Dobkin, obsessed with being an engineer
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #3 on: May 17, 2017, 11:49:06 pm »
I would think a small CPLD could do it, as long as you have the faster clock available to you - if you don't have the faster clock then you will need a PLL.  You will also need to think carefully about how you align the data to avoid slipping bits around (e.g. controlling the CS lines on the source).

Are you merging data from two SPI ADCs to an I2S stream?
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3146
  • Country: ca
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #4 on: May 18, 2017, 01:01:00 am »
A small dsPIC33FJ or PIC24HJ can do it.

You feed the input clock to the PIC's CLKI pin. It has built-in PLL. You use the PLL to produce 12x system frequency - if input is 7MHz then the system will run at 84 MHz, which means 42 MHz instruction clock.

You produce both CLK and H/L with built-in OC or PWM modules, so the CPU needs to only do A/B.

The CPU on these chips is 100% predictable - no cache or anything of that sort, so you can bit-bang with 100% surety. The output frequency is 14 MHz, so you will have 3 instructions to produce output, but you don't really need that many.

You select your pins to minimize overhead. For example, you can put your A and B inputs at RA0 and RA1. And you put your output at RC0. This way, you can read the byte from PORTA, and your input will contain A at bit 0 and B at bit 1.
 
To output A, you can simply copy the input byte to LATC and the A bit will go to RC0.

To output B, you use LSR instruction instead of copying. The instruction shifts the byte by one, so bit 1 will go directly to RC0, thus outputting the B bit.

Here's how your logic goes:

cycle 1. You read both A and B.

Code: [Select]
mov.b [w10],[w11++] ; w10 points to PORTA, w11 points to the buffer where you store data
cycle 2. You transmit the bit. If you need to transmit A, you do

Code: [Select]
mov.b [w12++],[w9] ; w9 points to LATC, w12 points to the memory location where previous data were stored
If you need to transmit B, you do

Code: [Select]
lsr.b [w12++],[w9] ; ibid
cycles 3-4. These cycles are for housekeeping

Here you may adjust w11/w12 so that they wrap around as needed

cycle 5. You transmit the second bit

cycle 6. Another housekeeping cycle


So, you just repeat these 6 steps 32 times and your data are out. This all takes 32 x 6 = 192 assembler instructions. Then you can jump back, or you can wrap them with DO instruction which does no-overhead looping and it will roll forever.

The only thing which requires work is to synchronize the CPU and both PWMs to the input clock, which may require some sort of calibration.

« Last Edit: May 18, 2017, 01:03:30 am by NorthGuy »
 
The following users thanked this post: stefan_o

Offline stefan_oTopic starter

  • Regular Contributor
  • *
  • Posts: 85
  • Country: de
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #5 on: May 19, 2017, 12:12:03 pm »
Thanks for all your great answers, since I never worked with FPGA/CPLDs before and them more complicated than expected, the solution NorthGuy proposed seems to be the best for me.
Since I use AVRs rather than PICs, is there an specific feature I have to use an PIC rather than an ATxmega? Only speed is a little lower, with slight overclocking I only get 6 cycles per input.
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19497
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #6 on: May 19, 2017, 02:25:23 pm »
That bit-bashing could easily be done in software with XMOS processors - and you would be able to guarantee it before executing the code :0

Currently I am making a reciprocal frequency counter using only software in a single XMOS processor to capture two 50Mb/s digital streams, count the edges in them, do some arithmetic, and pass the results over USB to a host processor. The latter would stretch the capabilities of most processors, but XMOS handles it easily, by design.

The timing is guaranteed by the development environment, so I know it can do that continuously without interruption (literally!).

The I/O and environment allows I/O to be done on specific clock cycles, with a 2ns resolution. There are many fpga-like I/O facilities including SERDES, handshakes, strobes, serial to parallel conversions etc.

For why those remarkable properties are true, see https://www.xmos.com/published/xcore-architecture?version=latest
Then try it with a £12 development board https://www.digikey.co.uk/en/product-highlight/x/xmos/startkit
The dev environment is free.

The code would be something like:

    in buffered port:32 aIn = XS1_PORT_1F; // the _1F specifies a single input pin, and the buffered port:32 specifies that 32 sequential bits are deserialised into a single word
    in buffered port:32 bIn = XS1_PORT_1G;
    out port dataOut = XS1_PORT_32B; // the 32 bit wide output port
    out port ab = XS1_PORT_1H; // a 1-bit port

    configure_clock_rate(clkIn, 500, 1); // 500MHz, or could use a clock arriving on an external pin
    configure_in_port(aIn, clkIn, 1);
    configure_in_port(bIn, clkIn, 1);

    configure_clock_rate(clkOut, 500, 32); // 1/32 of the clkIn, or could use a clock arriving on an external pin
    configure_out_port(data, clkOut, 1);
    configure_out_port(ab, clkOut, 1);
    start_clock(clkIn);   
    start_clock(clkOut);

    unsigned int aData;
    unsigned int bData;
    while (1) {
        aIn :> aData; // wait until 32 bits available, then continue
        bIn :> bData; // wait until 32 bits available, then continue
        ab <: 0; // which one
        dataOut <: aData; // output data one clock later,
        ab <: 1;  // other one
        dataOut <: bData;
    }

And that's it. But you could also specify that output occurs on clock cycle x with instructions like
    ab <: 1 @ x;
    dataOut <: aData @ x;
so that both change simultaneously.
« Last Edit: May 19, 2017, 02:50:16 pm by tggzzz »
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 
The following users thanked this post: stefan_o

Offline stefan_oTopic starter

  • Regular Contributor
  • *
  • Posts: 85
  • Country: de
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #7 on: May 19, 2017, 03:25:35 pm »
Thanks for your proposal, I do not understand your code example completely, first you fill buffer A complete, then buffer B, does this happen simultaneously?
You have the comment "output data one clock later,", how do you handle that one clock later?

Does the dev environment contain an emulator? So I can simulate an input signal and the output signal?
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19497
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #8 on: May 19, 2017, 05:45:49 pm »
There are many processors and a few languages; most are more-or-less interchangeable and all have similar disadvantages w.r.t. hard realtime systems. Learn one and the others are easy; don't bother to learn another until you have to.

The XMOS processors and xC language are significantly different and offer very significant advantages w.r.t. parallel processing and hard realtime systems. It is worth learning about them so that you can see the deficiencies in other techniques.

Thanks for your proposal, I do not understand your code example completely, first you fill buffer A complete, then buffer B, does this happen simultaneously?
You have the comment "output data one clock later,", how do you handle that one clock later?

Each port has its own SERDES register (and timer, and more), so bits are clocked in simultaneously as defined by clkIn. In that example, clkIn is 500MHz, but other frequencies can be chosen or it can come from another i/o pin.

The core is clocked at 100MHz, so the second bIn :> bData occurs 10ns after aIn :> aData. However, many many other variations are possible, and some may suit your purposes better. See https://www.xmos.com/download/private/Introduction-to-XS1-ports%281.0%29.pdf

Note also that these are multicore devices. The Startkit device is 8-core (plus another 8 cores dedicated to the USB interface).

It is entirely possible to have a separate core for each i/o "device", with the cores communicating over internal hardware links. For example, below chan means channel, chanend means channel end, and par means execute the functions in parallel, each on a separate core

void inputA(chanend foo) {
    while (1) {
        aPort :> aData;  // receive
        aData = aData - 1; // no idea why you would want to do that!
        foo :< aData;  // transmit to the process at the other end of the channel
    }
}

void inputB(chanend baz) {
    while (1) {
        aPort :> aData;  // receive
        aData = aData - 2; // no idea why you would want to do that!
        baz :< aData;  // transmit to the process at the other end of the channel
    }
}

void process(chanend bar1, chanend bar2) {
    while (1) {
        bar1 :> a; // receive
        bar2 :> b; // receive
        c = a + b; // i.e. c = inputA+inputB-3;
    }
}

chan linkA;
chan linkB;
par {
    // all these three functions execute simultaneously at 100MHz
    inputA(linkA);
    inputB(linkB);
    process(linkA, linkB);
}

Quote
Does the dev environment contain an emulator? So I can simulate an input signal and the output signal?

Download xTimeComposer from their website, and see. There is a simulator; I don't know whether it allows simulation of hardware inputs - but that doesn't matter. What you would do is create yet another process for each input, and use a link to connect the simulated output to the receiving processes. You can use the hardware timers to specify exactly which clock an output (or link) changes.

If you are familiar with Occam (from the 70s!) and/or Hoare's CSP (Communicating Sequential Processes) then you will feel comfortable with xC. FFI, see https://www.xmos.com/download/private/XMOS-Programming-Guide-%28documentation%29%28B%29.pdf

N.B. I have no connection with XMOS, but I have wanted to use CSP/Occam for hard realtime systems since the 70s :)
« Last Edit: May 19, 2017, 05:52:18 pm by tggzzz »
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 
The following users thanked this post: stefan_o

Offline stefan_oTopic starter

  • Regular Contributor
  • *
  • Posts: 85
  • Country: de
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #9 on: May 19, 2017, 08:08:48 pm »
I downloaded xTIMEcomposer and copy&paste your code for a start, but it gives me lot's of syntax errors, is it a problem in your code or am I doing something wrong?
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19497
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #10 on: May 19, 2017, 08:22:37 pm »
I downloaded xTIMEcomposer and copy&paste your code for a start, but it gives me lot's of syntax errors, is it a problem in your code or am I doing something wrong?

I haven't tried that code; it is pseudocode illustrating the language and hardware concepts and facilities. Nonetheless, you can use it as a close guide to what you might need to do.

I suggest you  take one of their examples, and mutate it in the direction I suggested.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 
The following users thanked this post: stefan_o

Offline stefan_oTopic starter

  • Regular Contributor
  • *
  • Posts: 85
  • Country: de
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #11 on: May 19, 2017, 10:54:10 pm »
I haven't tried that code; it is pseudocode illustrating the language and hardware concepts and facilities. Nonetheless, you can use it as a close guide to what you might need to do.

I suggest you  take one of their examples, and mutate it in the direction I suggested.
Ah ok, since I do neither know the language nor the specific instructions for the XMOS, I could not see that. I looked at several examples but I can't find anything that really explains how this asynchronous inputs/outputs work.
Is there any tutorial you can recommend for somebody how knows C but not XC that is more detailed on what exactly the instructions do compared to the comments in their examples?

Edit: I was able to modify/complete the source so it compiles. But I couldn't find out how to simulate it:
Code: [Select]
#include <xs1.h>
#include <platform.h>

in buffered port:32 aIn = XS1_PORT_1F; // the _1F specifies a single input pin, and the buffered port:32 specifies that 32 sequential bits are deserialised into a single word
in buffered port:32 bIn = XS1_PORT_1G;
out port dataOut = XS1_PORT_32B; // the 32 bit wide output port
out port ab = XS1_PORT_1H; // a 1-bit port

clock clkIn = XS1_CLKBLK_1;
clock clkOut = XS1_CLKBLK_2;

int main(void) {
    configure_clock_rate(clkIn, 500, 1); // 500MHz, or could use a clock arriving on an external pin
    configure_in_port(aIn, clkIn);
    configure_in_port(bIn, clkIn);

    configure_clock_rate(clkOut, 500, 32); // 1/32 of the clkIn, or could use a clock arriving on an external pin
    configure_out_port(dataOut, clkOut, 0);
    configure_out_port(ab, clkOut, 0);
    start_clock(clkIn);
    start_clock(clkOut);

    unsigned int aData;
    unsigned int bData;
    while (1) {
        aIn :> aData; // wait until 32 bits available, then continue
        bIn :> bData; // wait until 32 bits available, then continue
        ab <: 0; // which one
        dataOut <: aData; // output data one clock later,
        ab <: 1;  // other one
        dataOut <: bData;
    }
}
What I still don't get, what are blocking operations, what are non blocking? At the start you comment "wait until 32 bits available, then continue", does it wait or does it start to sample? "output data one clock later," Why is it one clock later? Does the <: operator copies the argument in some output buffer? aData and bData should be changing while outputting aData/bData
« Last Edit: May 20, 2017, 09:31:56 am by stefan_o »
 

Offline stefan_oTopic starter

  • Regular Contributor
  • *
  • Posts: 85
  • Country: de
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #12 on: May 20, 2017, 08:57:37 pm »
Code compiles and does not crash the simulator:
Code: [Select]
#include <xs1.h>
#include <platform.h>

in port inClock = XS1_PORT_1E;
in buffered port:32 aIn = XS1_PORT_1F; // the _1F specifies a single input pin, and the buffered port:32 specifies that 32 sequential bits are deserialised into a single word
in buffered port:32 bIn = XS1_PORT_1G;


out port outClock = XS1_PORT_1C; // a 1-bit port
out port dataOut = XS1_PORT_32B; // the 32 bit wide output port
out port ab = XS1_PORT_1H; // a 1-bit port

clock clkIn = XS1_CLKBLK_1;
clock clkOut = XS1_CLKBLK_2;

int main(void) {
    //configure_clock_rate(clkIn, 500, 1); // 500MHz, or could use a clock arriving on an external pin
    configure_clock_src(clkIn, inClock);
    configure_in_port(aIn, clkIn);
    configure_in_port(bIn, clkIn);

    //configure_clock_rate(clkOut, 500, 32); // 1/32 of the clkIn, or could use a clock arriving on an external pin
    configure_port_clock_output(outClock, clkOut);
    configure_out_port(dataOut, clkOut, 0);
    configure_out_port(ab, clkOut, 0);

    start_clock(clkIn);
    start_clock(clkOut);

    unsigned int aData;
    unsigned int bData;
    while (1) {
        aIn :> aData; // wait until 32 bits available, then continue
        bIn :> bData; // wait until 32 bits available, then continue
        ab <: 0; // which one
        dataOut <: aData; // output data one clock later,
        ab <: 1;  // other one
        dataOut <: bData;
    }
    return 0;
}
Beside the questions from previous post, what I could not find out, how do I multiply the clock? Output clock has to be twice of input clock. I found some information about PLL of system clock, do I need to synchronize the system clock with the input clock or is there another way?
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19497
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #13 on: May 20, 2017, 09:48:31 pm »
Ports: see Ports reference in reply #8
xC tutorial: see Programming Guide reference in reply #8
Simulation: probably in https://www.xmos.com/download/private/xTIMEcomposer-User-Guide-14%2814.x%29.pdf
Clocks: see first reference in https://www.google.co.uk/search?q=xmos+clocks
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline stefan_oTopic starter

  • Regular Contributor
  • *
  • Posts: 85
  • Country: de
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #14 on: May 21, 2017, 09:51:06 pm »
Sorry for all my questions, I never worked with XMOS before, I know AVR and for AVR there are hundreds of tutorials, examples and snippets for everything (even without including Arduino), compared to that there is basically nothing about XMOS.

I read those document about clocks before, I'm not sure, but I think there is a problem: The maximum input frequency is 6.144MHz, but the minimum is below 4MHz, I found another document that says minimum input frequency for PLL of the XMOS is 4.22 MHz.
Is there another option to double a frequency other than PLL? Or do I need external hardware and feed it into the device?

I modified the code and I am quite confident it should work, did not find a way to simulate input, but output seems to work.
Code: [Select]
#include <xs1.h>
#include <platform.h>

in port inClock = XS1_PORT_1E;
in buffered port:32 lIn = XS1_PORT_1F; // the _1F specifies a single input pin, and the buffered port:32 specifies that 32 sequential bits are deserialised into a single word
in buffered port:32 rIn = XS1_PORT_1G;


out port outClock = XS1_PORT_1C; // a 1-bit port
out buffered port:32 dataOut = XS1_PORT_1B; // the 32 bit wide output port
out buffered port:32 lrClock = XS1_PORT_1H; // a 1-bit port

clock clkIn = XS1_CLKBLK_1;
clock clkOut = XS1_CLKBLK_2;

int main(void) {
    configure_clock_src(clkIn, inClock);
    configure_in_port(lIn, clkIn);
    configure_in_port(rIn, clkIn);

    //configure_clock_rate(clkOut, 100, 10); // 1/32 of the clkIn, or could use a clock arriving on an external pin
    configure_port_clock_output(outClock, clkOut);
    configure_out_port(dataOut, clkOut, 0);
    configure_out_port(lrClock, clkOut, 0);

    start_clock(clkIn);
    start_clock(clkOut);

    unsigned int in_l_a=0;
    unsigned int in_r_a=0;
    unsigned int in_l_b=0;
    unsigned int in_r_b=0;

    const unsigned int high=0xfffffffe;
    const unsigned int low=0x1;
    while (1) {
        par {
            lIn :> in_l_a;
            rIn :> in_r_a;
            {
                par { lrClock <: high;
                    dataOut <: in_l_b; }
                par { lrClock <: low;
                    dataOut <: in_r_b; }
            }
        }
        par {
            lIn :> in_l_b;
            rIn :> in_r_b;
            {
                par { lrClock <: high;
                    dataOut <: in_l_a; }
                par { lrClock <: low;
                    dataOut <: in_r_a; }
            }
        }
    }
    return 0;
}
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19497
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #15 on: May 21, 2017, 10:51:51 pm »
I suggest you ask about the clocks on the XMOS forums.

Don't forget that you can specify that an input occurs on a specific clock cycle (a timed input) where the clock can be up to, I believe, 500MHz. You can use either common timers or the 16 bit counter in each up port.

I would have a separate process generating the simulated input, and connect that simulated input to your process via a channel.

You should verify whether your par statements will execute on one core or on different cores, and work out what is appropriate for you.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19497
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #16 on: May 22, 2017, 06:47:18 am »
It isn't clear to me how you know when to sample the external inputs, with xC or Arduino or anything else.

One mentality that you need to change with xC and the XMOS devices is that it is perfectly acceptable and normal to have one core completely halted, waiting for an input to come along. The other cores continue merrily, e.g. doing output.

Hence, if there is an external strobe/clock that doesn't fit the standard I/O port hardware, then can have an void inputProcess() {...} something like
while (1)
    // elegant way of waiting for an input condition or a timeout
    select {
        case inputClock when pinseq(1) :> dummy:
            // read data input
            // pass data through a channel to the output process
            break;
        case check on a timer for timeout
            // ...
           break
    }
    // or ugly spinloop waiting for another condition
    do {
        inputClock :> x;
    } while (input != 0);
}
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 
The following users thanked this post: stefan_o

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #17 on: May 22, 2017, 11:01:45 am »
If you were still open to an FPGA/CPLD solution, here's one that seems to work along the desired way, using a DDR output to avoid the need for a PLL

(see simulation below)

Code: [Select]
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

Library UNISIM;
use UNISIM.vcomponents.all;

entity merge is
    Port ( clk : in STD_LOGIC;
           in_a   : in STD_LOGIC;
           in_b   : in STD_LOGIC;
           out_lr : out STD_LOGIC;
           out_d  : out STD_LOGIC);
end merge;

architecture Behavioral of merge is

    signal in_sr_a   : std_logic_vector(15 downto 0) := (others => '0'); -- input shift register
    signal in_sr_b   : std_logic_vector(15 downto 0) := (others => '0'); -- input shift register
    signal out_sr_d  : std_logic_vector(31 downto 0) := (others => '0'); -- output shift register
    signal out_sr_lr : std_logic_vector(31 downto 0) := (others => '0'); -- output shift register for LR clk
    signal count     : unsigned(3 downto 0)          := (others => '0');
begin


ODDR_lr : ODDR
   generic map(DDR_CLK_EDGE => "SAME_EDGE", INIT => '0', SRTYPE => "SYNC")
   port map (
      Q => out_lr, C => clk, CE => '1',
      D1 => out_sr_lr(0),
      D2 => out_sr_lr(1),
      R => '0', S => '0'
   );

ODDR_d : ODDR
   generic map(DDR_CLK_EDGE => "SAME_EDGE", INIT => '0', SRTYPE => "SYNC")
   port map (
      Q => out_d, C => clk, CE => '1',
      D1 => out_sr_d(0),
      D2 => out_sr_d(1),
      R => '0', S => '0'
   );

process(clk)
    begin
        if rising_edge(clk) then
           if count = 15 then
              out_sr_d  <= in_sr_a & in_sr_b;
              out_sr_lr <= x"80007FFF";
              count     <= (others => '0');
           else
              out_sr_d  <= "00" & out_sr_d(31 downto 2);     
              out_sr_lr <= out_sr_lr(1 downto 0) & out_sr_lr(31 downto 2);     
              count <= count+1;
           end if;
          in_sr_a <= in_a & in_sr_a(15 downto 1);
          in_sr_b <= in_b & in_sr_b(15 downto 1);
        end if;
    end process;
end Behavioral;
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 
The following users thanked this post: stefan_o

Offline agehall

  • Frequent Contributor
  • **
  • Posts: 383
  • Country: se
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #18 on: May 22, 2017, 01:38:33 pm »
OT: I'd never heard of XMOS processors before but after reading up about them, they seem freaking awesome! I have to get me some of that magic sauce me thinks! Thanks for putting me onto those little gems.
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19497
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #19 on: May 22, 2017, 02:44:38 pm »
OT: I'd never heard of XMOS processors before but after reading up about them, they seem freaking awesome! I have to get me some of that magic sauce me thinks! Thanks for putting me onto those little gems.

All tools and technologies have "rough edges", but these remove many rough edges in traditional tools.

I'm still learning about the XMOS toolchain; but I like its pedigree and so far I haven't found any fundamental problems.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3146
  • Country: ca
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #20 on: May 22, 2017, 04:32:34 pm »
If you were still open to an FPGA/CPLD solution, here's one that seems to work along the desired way, using a DDR output to avoid the need for a PLL

I agree. If you want something new and interesting to learn, go with real FPGA and VHDL/Verilog. These are completely different from C/asm (or anything you can find on MCU) and they are extremely powerful and flexible.

 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19497
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #21 on: May 22, 2017, 04:46:36 pm »
If you were still open to an FPGA/CPLD solution, here's one that seems to work along the desired way, using a DDR output to avoid the need for a PLL

I agree. If you want something new and interesting to learn, go with real FPGA and VHDL/Verilog. These are completely different from C/asm (or anything you can find on MCU) and they are extremely powerful and flexible.

They are indeed.

They also have a significant learning curve, related to the "hardware mentality", the language itself, and the complexity of toolchains. The first two are inevitable; the last is irritating and has to be dealt with.

Sometimes only one technology will solve the problem; more often several technologies could solve the problem. Knowing multiple technologies allows selection of the most appropriate for the task, so that you avoid using a hammer to insert nails.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Online helius

  • Super Contributor
  • ***
  • Posts: 3642
  • Country: us
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #22 on: May 22, 2017, 05:24:15 pm »
Sometimes only one technology will solve the problem; more often several technologies could solve the problem. Knowing multiple technologies allows selection of the most appropriate for the task, so that you avoid using a hammer to insert nails.
I think everybody knows what you're getting at, but avoiding using a hammer to insert a nail is a good metaphor for how perverse many hobbyist projects can be.
 
The following users thanked this post: Kilrah

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19497
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #23 on: May 22, 2017, 05:41:30 pm »
Sometimes only one technology will solve the problem; more often several technologies could solve the problem. Knowing multiple technologies allows selection of the most appropriate for the task, so that you avoid using a hammer to insert nails.
I think everybody knows what you're getting at, but avoiding using a hammer to insert a nail is a good metaphor for how perverse many hobbyist projects can be.

Aaargh! Doh! :)

I agree, but there can be good reasons for using a new technology on a simple "hobbyist" project: to see whether it lives up to its promise, or just to see how far things can be pushed before they break.

Two examples from my recent experience are using a cheap SDR dongle as a network analyser and TDR, and making an Fin/Freffrequency counter using software alone. The former can resolve impedance discontinuities ~3cm apart, the latter works with a 12.5MHz frequency inputs (and possibly 25MHz).
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3146
  • Country: ca
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #24 on: May 22, 2017, 05:53:07 pm »
They also have a significant learning curve, related to the "hardware mentality", the language itself, and the complexity of toolchains. The first two are inevitable; the last is irritating and has to be dealt with.

Yes, tools are horrible. I can only speak of Xilinx. They had ISE. Now they came up with new tool, called Vivado. It is very big (20GB download), slow, and not very well thought out. But if you manage to get through it, it is worth it.

The FPGA mentality is indeed completely different. If learning is a part of your goal, it is a fascinating thing to try. It will broaden your perspective and will give you a different view. Of course, it costs more, but ...
 

Offline stefan_oTopic starter

  • Regular Contributor
  • *
  • Posts: 85
  • Country: de
Re: Reorder/multiplex bitstreams (FPGA needed?)
« Reply #25 on: June 11, 2017, 10:39:21 pm »
If you were still open to an FPGA/CPLD solution, here's one that seems to work along the desired way, using a DDR output to avoid the need for a PLL

(see simulation below)

Code: [Select]
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

Library UNISIM;
use UNISIM.vcomponents.all;

entity merge is
    Port ( clk : in STD_LOGIC;
           in_a   : in STD_LOGIC;
           in_b   : in STD_LOGIC;
           out_lr : out STD_LOGIC;
           out_d  : out STD_LOGIC);
end merge;

architecture Behavioral of merge is

    signal in_sr_a   : std_logic_vector(15 downto 0) := (others => '0'); -- input shift register
    signal in_sr_b   : std_logic_vector(15 downto 0) := (others => '0'); -- input shift register
    signal out_sr_d  : std_logic_vector(31 downto 0) := (others => '0'); -- output shift register
    signal out_sr_lr : std_logic_vector(31 downto 0) := (others => '0'); -- output shift register for LR clk
    signal count     : unsigned(3 downto 0)          := (others => '0');
begin


ODDR_lr : ODDR
   generic map(DDR_CLK_EDGE => "SAME_EDGE", INIT => '0', SRTYPE => "SYNC")
   port map (
      Q => out_lr, C => clk, CE => '1',
      D1 => out_sr_lr(0),
      D2 => out_sr_lr(1),
      R => '0', S => '0'
   );

ODDR_d : ODDR
   generic map(DDR_CLK_EDGE => "SAME_EDGE", INIT => '0', SRTYPE => "SYNC")
   port map (
      Q => out_d, C => clk, CE => '1',
      D1 => out_sr_d(0),
      D2 => out_sr_d(1),
      R => '0', S => '0'
   );

process(clk)
    begin
        if rising_edge(clk) then
           if count = 15 then
              out_sr_d  <= in_sr_a & in_sr_b;
              out_sr_lr <= x"80007FFF";
              count     <= (others => '0');
           else
              out_sr_d  <= "00" & out_sr_d(31 downto 2);     
              out_sr_lr <= out_sr_lr(1 downto 0) & out_sr_lr(31 downto 2);     
              count <= count+1;
           end if;
          in_sr_a <= in_a & in_sr_a(15 downto 1);
          in_sr_b <= in_b & in_sr_b(15 downto 1);
        end if;
    end process;
end Behavioral;
That looks really interesting, but at the moment this seems a bit too complex for me. But I will definitely keep that in mind, especially the trick of using DDR outputs.  In fact this problem is more complex than I originally thought, it would add to much cost and effort to the entire project.
Thank you all for your help!
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf