Boneless CPU and nMigen stuff


Shortly both of my new Bx’s will be here.

I have been working on something for the last few weeks and I will be able to put it on silicon as gateware.

I have taken whitequarks Boneless-CPU design that she has ported across to nMigen.

So I though it would be a good idea to write an text assembler.

its here , my addition is inside boneless/assembler folder and I have moved a [simulator] ( in as well.

I hope to get it running on my bx. There is a working python emulator and some asm programs already.

I will need to get a USB serial port connected to the CPU.

The Boneless-CPU is a 16bit processor that has no frills and packs into 500ish LUT + RAM. The ISA is clean but still in flux.

My long term goal is to finish writing a FORTH in assembly for it and making a multitool bootloader. This could load and save images on and off the flash and keep config on flash.


Waiting for my hardware.


Sounds like a really fun project! Keep us posted with updates, pictures, and code! :slight_smile:


Building some install scripting and a demo CPU.



They have arrived, now for some more caffeine and some late nights …


Well, that was easier than expected. BLINKY!!!

New photo by Simon Kirkby


Managed 5 blinking lights from nmigen. , the cpu is loading but not running yet…


Success with the Boneless CPU and some blinky.

nxtpnr seems to think it can do 54 MHz, perhaps this can run off the 48MHz usb clock once I have a serial port.

Info: Max frequency for clock ‘clk_$glb_clk’: 54.79 MHz (PASS at 12.00 MHz)


Running on a gateware processor @16Mhz with this

The next step is to get a USB serial port running and interface it to the processor. Then a serial monitor to send/receive/call into memory on the device.


Video or it didn’t happen


…and i’ve bricked the bootloader.

when you are updating the bootloader , do not press reset after stage 1 and before stage 2.

Activating backup TinyFPGA

Now digging for recovery threads in this place…


Soldered SPI onto the underside of my the first BX , turns out that I didn’t brick the boot loader , the USB hub was being weird , anyway , At least I can Experiment later.

So onto the job at hand, the serial port , I grabbed and tried it out , built first time and did the echo on a screen session to /dev/ttyACM0. I transfered the reset code and the pll across to the Boneless, fiddled around a bit and got processor running at 48Mhz.

I had to increase the wait loop in the asm code so I could see the blinky running :rofl:

Next I have to wrap davidthings serial port onto the CPU , this should not be too hard because it will be running off the same clock.

Then , debug the serial monitor ( and it should be an interactive session.

I have also started a SOC thing ( that will be able to attach gateway in python. I will need to port the CPU across to it.

…onwards! :vulcan_salute:


Wowzers ! this has been far less painful than I had anticipated.

I have a working usb serial port and a Boneless-CPU running on the tinyFPGA-BX on the same clock.

Has the code, it runs.

I have 4 LEDs on P12,13,14,15 for blinkage.

tomorrow … more work.


Hit a bit of a wall,

The code is here

I’m attempting to connect the uart to the cpu , but I’m getting some weird errors when I try to synthesize.

Warning: multiple conflicting drivers for boneless_tbx.\cpu.usb_out_control [0]:
port Q[0] of cell $techmap\cpu.$procdff$7117 ($dff)
port Q[0] of cell $techmap\uart.uart.usb_uart_bridge_ep_inst.$procdff$6978 ($dff)
Warning: Wire boneless_tbx.\cpu.usb_in_control [2] is used but has no driver.
Warning: Wire boneless_tbx.\cpu.usb_in_control [0] is used but has no driver.
Warning: Wire boneless_tbx.\cpu.usb_in_data [7] is used but has no driver.

I’m not sure why this is happening as my Verilog FU is not wonderful

The top level file is

I’m hooking up wires to connect it to the cpu. The weird thing is that the leds section is set up the via top level outputs and is not getting the same error.

Can anyone advise what i’m doing wrong ?


Super quickly looking at the top layer, is it possible that it’s an IN vs OUT problem? Maybe USB_IN which is in to the USB module is an output for your processor?

USB code

module usb_uart_i40 (
input  clk_48mhz,
input reset,

// USB pins
inout  pin_usb_p,
inout  pin_usb_n,

// uart pipeline in (out of the device, into the host)
input [7:0] uart_in_data,

Boneless Core

(* src = "" *)
input [15:0] usb_in_control;
(* src = "" *)
input [15:0] usb_in_data;

Then the joining

boneless_core cpu(

Your error could be just addressing the fact that the outputs are in a pissing competition and the inputs are lonely.

What is the right convention to adopt with these in and out labels?


You were right, the directions are in the sense of the host , not the device. Perhaps they should be from_host and to_host to prevent confusion.

Getting closer…

What does a single byte transaction look like for the valid and ready signals?

I think i may need two fifos to buffer the flow a bit.

So close… :slight_smile:


Check out this excellent description of the interface.

Here’s a crude screen grab from P3 that covers it. This image is long… click on it to see the whole thing.


Here’s the FIFO I use:

module pipeline_fifo #( parameter Width = 8, parameter MemoryWidth = 3 ) (
    input clock,
    input reset,

    input [Width-1:0]  in_data,
    input              in_valid,
    output             in_ready,

    output [Width-1:0] out_data,
    output             out_valid,
    input              out_ready

reg [Width-1:0] memory [0:1<<MemoryWidth];

// MemoryWidth + 1 (extra rX, wX, so read != write when full)
reg [MemoryWidth:0] read_address;
reg [MemoryWidth:0] write_address;

// Are we ready? There's room if r != w or rX == wX
assign in_ready = ( read_address[MemoryWidth] == write_address[MemoryWidth] ) ||
                  ( read_address[MemoryWidth-1:0] != write_address[MemoryWidth-1:0] );

// Write logic
always @(posedge clock) begin
    if ( reset ) begin
        write_address <= 0;
    end else begin
        if ( in_ready ) begin
            if ( in_valid ) begin
                memory[ write_address[MemoryWidth-1:0] ] <= in_data;
                write_address <= write_address + 1;

// Are we valid? (any time the whole read and write addresses are not exactly equal)
assign out_valid = ( read_address != write_address );

// Read logic
always @(posedge clock) begin
    if ( reset ) begin
        read_address <= 0;
    end else begin
        if ( out_valid ) begin
            if ( out_ready ) begin
                read_address <= read_address + 1;

assign out_data  = ( out_valid ) ? memory[ read_address[MemoryWidth-1:0] ] : 0;



Thanks for that David,

I’m going to try to use nMigen constructs so I can do some meta programming at that level. Thanks though , I will stash that verilog in my toolbox.

I did have a thought last night. Down the bottom of the usb stack is this rom.

Would it be possible to lift this all the way to the top level and mux it , possibly even enumerate all 8 endpoints?

That way the boneless at the top could create usb endpoints at will. I’ll have three webcams and 5 serial ports pls. :wink:

If you have the interest , can you pass your eye over and critique please.

My intent is to get a console ( with ansi graphics ) running on the Bx.



I love the idea of having more endpoints. Maybe a future project…


As much as there has been no action on this thread, I have been busy.

New photo by Simon Kirkby

it has an Arduino nano pro running a h-bridge controller. I have a 5 <-> 3.3 volt converter and my BX is going to be the brain.