FPGA implementation

An investigation into the behaviour of the Yamaha OPL3 chipset.
With a view to a more accurate emulator

Re: FPGA implementation

Postby synthop » Sun Nov 30, 2014 6:31 pm

The project is up on Github: https://github.com/gtaylormb/opl3_fpga

I'm new to Github so I'm still figuring things out--let me know if I should change anything.
synthop
 
Posts: 33
Joined: Sun Oct 26, 2014 9:21 pm
Location: Brooklyn, New York, USA

Re: FPGA implementation

Postby sto » Mon Dec 01, 2014 5:17 am

Just a few things:
1) It seems you switched the feedback writes; it's a cyclic buffer, and you do something like [0]<=fb; [1]<=[0], but those should be switched; you could of course also use the vibrato counter LSB as an index into the array.
2) Can you recommend any free SystemVerilog simulator (i.e. without the need for hardware)? I'm thinking about playing around a bit with your code; I'm using both Windows and Linux, if that matters, and I'm not afraid of CLI.
3) You may add the PPPlay code (please note it's not "peepeeplayer" anymore, as that was a quite bad choice, obviously) as a git submodule; submodules are references to other repositories, so you don't need to copy over that code (see http://git-scm.com/book/en/v2/Git-Tools-Submodules).

Cheers
sto
 
Posts: 60
Joined: Thu Nov 08, 2012 4:33 am

Re: FPGA implementation

Postby synthop » Mon Dec 01, 2014 1:00 pm

I *think* the order doesn't matter because both array entries are just added together:

Code: Select all
    always_ff @(posedge clk)
        if (sample_clk_en) begin
            feedback[bank_num][op_num][0] <= out;
            feedback[bank_num][op_num][1] <= feedback[bank_num][op_num][0];
        end
   
    always_comb
        feedback_result = ((feedback[bank_num][op_num][0] + feedback[bank_num][op_num][1]) << fb) >> 9;


Vs.

Code: Select all
    int16_t feedback() const {
        if( m_fb == 0 ) {
            return 0;
        }
        return ( ( m_feedback[0] + m_feedback[1] ) << m_fb ) >> 9;
    }
    /**
     * @brief Push feedback into the queue
     * @param[in] fb 13 bit feedback from channel output
     */
    void pushFeedback( int16_t fb ) {
        m_feedback[0] = m_feedback[1];
        m_feedback[1] = fb;
    }


But, your comment did make me realize I was updating on every clock edge and not the sample_clk_en (fixed above), so that was incorrect.

I would try the Xilinx Vivado simulator that comes with the Vivado WebPack. The Linux version seemed to crash on me, so you might try the Windows version. There's also a free version of Modelsim you can download from the Alterra website, though it might be quite slow (they intentionally slow it down).

Also thanks for the heads up about the submodule reference. I'll add your code in.
synthop
 
Posts: 33
Joined: Sun Oct 26, 2014 9:21 pm
Location: Brooklyn, New York, USA

Re: FPGA implementation

Postby sto » Mon Dec 01, 2014 4:15 pm

But it's still a difference between
Code: Select all
x0=out; x1=x0;

and
Code: Select all
x1=x0; x0=out;

because in the first case you're using only the last output sample (x1=x0=out), where in the latter one you're using the average value of the last 2 output samples (which, btw, is patented somewhere).
sto
 
Posts: 60
Joined: Thu Nov 08, 2012 4:33 am

Re: FPGA implementation

Postby synthop » Mon Dec 01, 2014 4:40 pm

The confusion lies in how HDLs work. Those statements are concurrent not sequential; the order actually doesn't matter as it would in software.

Code: Select all
    always_ff @(posedge clk)
        if (sample_clk_en) begin
            feedback[bank_num][op_num][0] <= out;
            feedback[bank_num][op_num][1] <= feedback[bank_num][op_num][0];
        end


is exactly the same as:

Code: Select all
    always_ff @(posedge clk)
        if (sample_clk_en) begin
            feedback[bank_num][op_num][1] <= feedback[bank_num][op_num][0];
            feedback[bank_num][op_num][0] <= out;
        end


This is a fundamental difference between software and hardware design.
synthop
 
Posts: 33
Joined: Sun Oct 26, 2014 9:21 pm
Location: Brooklyn, New York, USA

Re: FPGA implementation

Postby sto » Mon Dec 01, 2014 4:47 pm

Then I guess it's time for me to learn something new ;)
sto
 
Posts: 60
Joined: Thu Nov 08, 2012 4:33 am

Re: FPGA implementation

Postby synthop » Mon Dec 01, 2014 5:14 pm

Yeah this is perhaps the most common misconception of someone coming from software. It takes a bit of getting used to. Putting it in a simulator and visualizing it helps a lot.

Registers are updated simultaneously on the rising clock edge; x0 gets the current sample, x1 gets the *previous* value of x0. The *new* value of x0 has not yet propagated to the input of x1. The order in which you put the statements doesn't matter.
synthop
 
Posts: 33
Joined: Sun Oct 26, 2014 9:21 pm
Location: Brooklyn, New York, USA

Re: FPGA implementation

Postby opl3 » Mon Dec 01, 2014 9:18 pm

Alright, the Zybo arrived last week, had some time to try out the demo project.

Still have not installed the Zybo developement tools (I'd install in Linux but you said it does not work so well so maybe I have to install it in Windows 7, right?).

I saw the project on Github, thank you, I have to check it out (literally :) ). Any crash course how to open it (ISE/Vivado?) and "build" it? If you have a Zybo binary to put on an SD card, I can also try it out if it does something by itself.

It is a very nice idea to put Sto's player there to have something to play, but I can also provide my own DRO/IMF/LAA routines if necessary. I think AdPlug may calculate IMF/LAA playing tempo a bit off.
opl3
 
Posts: 55
Joined: Sun Sep 26, 2010 8:11 pm

Re: FPGA implementation

Postby synthop » Mon Dec 01, 2014 10:11 pm

Cool.

I have no idea if the Windows version of Vivado works better, just a guess. With the exception of the simulator, the Linux tools work great--YMMV. There are newer versions of Vivado out since I last tried simulation in Linux, so I'd give it a go. For now I do my development in Linux and only resort to Windows/Cygwin for simulation. I use Modelsim for my simulator and only have a Windows version...

I do all CLI building using Makefiles. If Vivado is installed and in the PATH, you can simply run 'make bitstream' to get a bitstream which you can load via the USB JTAG cable to your board. I have a 'make program' target which programs my board but I think it's specific to my board address/serial number (you probably just have to modify it). I haven't created an SD card image yet.

I also have simulation targets in the Makefile for Modelsim. You should be able to add in Vivado ones (or I may at some point).
synthop
 
Posts: 33
Joined: Sun Oct 26, 2014 9:21 pm
Location: Brooklyn, New York, USA

Re: FPGA implementation

Postby Dongulus » Thu Dec 11, 2014 7:32 pm

Hello synthop,
I've successfully followed you here from your Reddit post and so far I've only just glanced over your GitHub. Coming from a PL background and only a basic knowledge of audio synthesizers, I'm trying to get an understanding of the system level overview and features for the OPL-3. Could you point me to a document that would help me with this, or maybe you could offer a brief description of the architecture for this chip?
Dongulus
 
Posts: 2
Joined: Mon Dec 08, 2014 7:07 pm
Location: San Diego, California

PreviousNext

Return to Yamaha OPL-3 research

Who is online

Users browsing this forum: No registered users and 12 guests

cron