Last visit was: Mon Dec 09, 2024 7:39 am
It is currently Mon Dec 09, 2024 7:39 am



 [ 108 posts ]  Go to page 1, 2, 3, 4, 5 ... 8  Next
 One Page Computing - roll your own challenge 
Author Message

Joined: Wed Jan 09, 2013 6:54 pm
Posts: 1807
.
Last week, over a curry, we(*) developed an idea: a computing challenge which involves a single page of source, or several sources each a single page. But you make up your own mind about exactly what that means: your own CPU, your own SBC, your own HLL...

The launching point was revaldinho's OPC project, which is a homebrew CPU and which chooses to define a single page as a 66-line page of green bar fanfold, with lines up to 100 characters. In that case, the idea is to have concise but readable source. Presently that project has
- a one-page spec
- a one-page Verilog model of the CPU
- a one-page testbench which fleshes out the CPU with storage
- a one-page test program (a work in progress!)
- a one-page assembler (in Python)
- a one-page emulator in Python, and another in JavaScript
(all of these language choices being just the preferences for this project, not a definition of the challenge)

The original idea was also to keep the CPU simple enough to fit on a 9572 CPLD. (But it might turn out to be more interesting to put it on FPGA. Or to make that a second entry for the challenge - less of a resource constraint, so free to make a more amenable CPU.)

Another idea of course is to make a CPU using TTL, or an SBC using a microprocessor, in which case you might choose these constraints
- a one-page schematic
- a single small PCB - perhaps Eurocard size, or perhaps smaller - or a single breadboard or a single perfboard

And then, there's a variety of one-page software projects possible:
- a one-page monitor, written in assembly
- a one-page HLL, as a cross-compiler written in say Go or Python

I quite like the idea of everyone being able to set their own goals and their own constraints. For example. you can get 88 lines on a sheet of fanfold with some printers! And a line length up to 132 would be historically appropriate too.

What do we think?

(*) - we, being me, revaldinho, and hoglet.


Tue Apr 25, 2017 9:26 am

Joined: Wed Apr 24, 2013 9:40 pm
Posts: 213
Location: Huntsville, AL
Sounds like a great challenge. I might be interested in working on this. I'd like to recommend not restricting the implementation languages to just Python and Javascript. I am thinking that Lua may also be an appropriately well supported scripting language that could be included as an option for implementing the assembler and emulators.

_________________
Michael A.


Tue Apr 25, 2017 9:53 am

Joined: Tue Jan 15, 2013 10:11 am
Posts: 114
Location: Norway/Japan
Butbutbut.. all my printouts from Way Back Then were in blue bar fanfold (except when they were in grey bar fanfold). Lots of old 132-col printouts still stacked here..

Other than that.. :) - great idea! Well, I don't do Javascript, Python, or even Lua (got slightly offended by the '~=' operator (what's wrong with '!=' ?), so I'll get back to it after some rest). But yes, good idea.


Tue Apr 25, 2017 10:28 am

Joined: Wed Jan 09, 2013 6:54 pm
Posts: 1807
Oh, absolutely, use any language you choose! In fact I'm told an inspiration for the project and for the assembler was the example in the awk book.

And any colour of fanfold. We did have some debate about the music-stave style which only really allows for 66 lines, and the green-boxes style which also works for 88 lines.

What we don't have yet is any kind of attractive photo or image to illustrate the idea: we need some hardware, and perhaps some fanfold as a backdrop, if we can find some. Or print some...

(I expect that a single page project in C++ or Java or Cobol might be more difficult than in Python, Lua or Ruby ... likewise I suspect Verilog might have a density advantage over VHDL, but that's all part of the challenge, to choose a constraint and try to meet it.)


Tue Apr 25, 2017 3:46 pm

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2231
Location: Canada
Seems like an interesting challenge. I have wanted to write something smaller. But my concept of small is skewed. I don’t think I can fit anything into less than 10 pages. Even a lowly 6502 is about 400 to 600 lines of code.
Quote:
Other than that.. - great idea! Well, I don't do Javascript, Python, or even Lua (got slightly offended by the '~=' operator (what's wrong with '!=' ?), so I'll get back to it after some rest). But yes, good idea.

It seems nobody can get the operator right. It should be ‘<>’ :) I get offended by ‘/=’ in VHDL. So now there’s another <> operator I’ve learned about.

_________________
Robert Finch http://www.finitron.ca


Tue Apr 25, 2017 5:10 pm WWW

Joined: Wed Jan 09, 2013 6:54 pm
Posts: 1807
Yes, it's surely not going to be a 6502. An accumulator machine is evidently possible. A microcoded machine might be able to do more, especially if you put the microcode into a different single-page source file. A stack machine or a RISC machine might be OK too. Picking a suitable word width might help, by keeping the decode very simple. Things like variable instruction lengths, and having full size pointers the same width as the instruction word might be impediments. I think this kind of project is nice in forcing a design which is simple.


Tue Apr 25, 2017 5:39 pm

Joined: Wed Apr 24, 2013 9:40 pm
Posts: 213
Location: Huntsville, AL
BigEd wrote:
Oh, absolutely, use any language you choose! In fact I'm told an inspiration for the project and for the assembler was the example in the awk book.

The assembler I wrote to support my ongoing effort to port the Ron Mak Pascal compiler to my M65C02A core is written in AWK. I agree the associative arrays of AWK, which are greatly enhanced in Lua, were key to implementing a compact representation for the opcodes that I make use of in the code generator for the Pascal compiler.
Tor wrote:
even Lua (got slightly offended by the '~=' operator (what's wrong with '!=' ?)
I found that a bit strange as well. Must be a northern hemisphere vs. southern hemisphere thing. :D

_________________
Michael A.


Wed Apr 26, 2017 1:57 am
User avatar

Joined: Tue Jan 15, 2013 5:43 am
Posts: 189
BigEd wrote:
But you make up your own mind about exactly what that means: your own CPU, your own SBC, your own HLL...
Hmm, the terms are really quite broad. It seems you're inviting folks to post whatever they like as long as it's small-ish (and interesting) -- and I'm OK with that! :D

revaldinho's OPC Project definitely qualifies! I like how the computer only supports 2 addressing modes: immediate and direct. With this level of simplicity even a CPLD is optional. :shock: Here is an all-TTL computer I encountered (and hacked) years ago. Like the OPC, it is fully functional despite being desperately simple! But this is a commercial product, not original work by a forum member.

In the original work category, I humbly submit my One-bit Computer. Although the project is noted elsewhere on Anycpu.org it certainly seems topical to this thread. BTW that's not a typo at the bottom of the diagram. This processor really does feature I/O-mapped memory! :mrgreen:

-- Jeff
Attachment:
3200 State machine small.gif


Edit: per Ed's suggestion below, here is an image of the board -- taken with a photocopier! That was a quick 'n dirty documentation shortcut I used often in the days before digital photography.

There's a 7805 voltage regulator along the left side at the top, and you can see the homebrew heatsink attached. This board was made by hand, using wire-wrap. Two of the wire-wrap sockets (arranged horizontally in the lower half) don't contain IC's; instead they accept DIP connectors carrying signals to/from the host device -- the printing press. For more info visit the linked page.
Attachment:
One-bit bd layout.jpg


You do not have the required permissions to view the files attached to this post.

_________________
http://LaughtonElectronics.com


Last edited by Dr Jefyll on Wed Apr 26, 2017 4:48 pm, edited 1 time in total.



Wed Apr 26, 2017 3:22 am WWW

Joined: Wed Jan 09, 2013 6:54 pm
Posts: 1807
If it fits on a page Jeff, it's fit for the challenge! (Do you have a photo of the implementation at all?)

We did wonder what would constitute a demonstration that the one-page creation is indeed a computer. For me, controlling some hardware according to a program is ample demonstration.

But for more conventionally computational offerings, I was thinking of some kind of demo program. Because of who I am and where I come from, I was thinking of something based on numbers - which could of course be done in binary using toggles and LEDs, or could be serial ASCII, or a keyboard and video out, or a number of other possibilities.

The numerical ideas I had:
- print out the first N squares [1]
- the first N Fibonacci numbers
- the first N primes
- the first N square roots
- the first N digits of e
- the first N digits of pi
- Mastermind / cows and bulls game
- Higher/Lower guess a number game
- Lunar Lander game (not real time, of course! Turn-based.)

[1] Historically interesting: EDSAC ran a squares and differences program written by Wilkes. It had multiplication, so squaring was easy, but printing numbers in decimal always takes effort.
http://www.cl.cam.ac.uk/~mr10/edsacposter.pdf

Running any kind of HLL interpreter would support any of those programs, but they could equally well be written in assembler.

For the one-bit state machine computer, perhaps a little more tricky. Perhaps it could be programmed as a binary adder/subtracter - a calculator of sorts? Or if not binary, perhaps unary?


Wed Apr 26, 2017 5:50 am
User avatar

Joined: Tue Jan 15, 2013 5:43 am
Posts: 189
BigEd wrote:
(Do you have a photo of the implementation at all?)
Happy to oblige -- I've added it to my post above. :)

_________________
http://LaughtonElectronics.com


Wed Apr 26, 2017 4:49 pm WWW

Joined: Wed Jan 09, 2013 6:54 pm
Posts: 1807
A photocopy - excellent! Thanks!


Wed Apr 26, 2017 5:01 pm

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2231
Location: Canada
I have taken up the one page challenge. The cpu core fleshed out to about 2 pages total of Verilog, so I broke it up into stages each with it's own page in part because I might want to expand upon it. I have only included the outermost Verilog here to avoid cluttering up the messages.

Trace of instruction execution for incrementing counter.
Attachment:
Presentation1.png


// OPCX spec sheet
//
// 32 bit wide data path, 32 bit addresses
// 64 registers with R0 always equal to zero
// No flags
// About 20 instructions
// op = 6 bit opcode
// Ra = operand register A
// Rb = operand register B
// Rt = target register
//
// RI - Register Immediate
// +------------+----+----+----+
// | immed14 | Rt | Ra | op |
// +------------+----+----+----+
// 04 ADDI
// 06 CMPI
// 08 ANDI
// 09 ORI
// 0A XORI
// 0C LD
// 0D ST
// 0E JAL
//
// IMM
// +-----------------+----+----+
// | immed32..12 | -- | 0F |
// +-----------------+----+----+
// Immediate prefix extends the immediate constant of the following instruction.
//
// B - Branch
// +------------+----+----+----+
// | disp14 | Cn | Ra | 0B |
// +------------+----+----+----+
// 0 BEQ
// 1 BNE
// 2 BPL
// 3 BMI
//
// RR - Register Register
// +----+-+----+----+----+----+
// | fn | | Rt | Rb | Ra | 02 |
// +----+-+----+----+----+----+
//
// 00 SHL
// 01 SHR
// 04 ADD
// 05 SUB
// 06 CMP
// 08 AND
// 09 OR
// 0A XOR

Code:
// One Page Challenge CPU
module OPCX(rst,clk,wr,adr,dato,dati);
parameter DBITS = 32;
input rst;
input clk;
output reg wr;
output reg [DBITS-1:0] adr;
output reg [DBITS-1:0] dato;
input [DBITS-1:0] dati;

reg [DBITS-1:0] ir;
reg [DBITS-1:0] pc;
wire [5:0] Ra = ir[11:6];
wire [5:0] Rb = ir[17:12];
reg [5:0] Rt;
reg [DBITS-1:0] regfile [63:0];
reg immf;
reg [DBITS-1:0] a,b,imm,res;

parameter RESET = 3'd0;
parameter IFETCH1 = 3'd1;
parameter IFETCH2 = 3'd2;
parameter DECODE = 3'd3;
parameter EXECUTE = 3'd4;
parameter MEM1 = 3'd5;
parameter MEM2 = 3'd6;
reg [2:0] state;

always @(posedge clk)
if (rst)
    next_state(RESET);
else begin
wr <= 1'b0;
case(state)
`include "OPCX_Reset.vh"
`include "OPCX_IFetch.vh"
`include "OPCX_Decode.vh"
`include "OPCX_Execute.vh"
`include "OPCX_Memory.vh"
endcase
end

task next_state;
input [2:0] st;
begin
    case(st)
    RESET:  $display("RESET");
    IFETCH1: $display("IFETCH1");
    IFETCH2: $display("IFETCH2");
    DECODE: $display("DECODE");
    EXECUTE: $display("EXECUTE");
    MEM1: $display("MEM1");
    MEM2: $display("MEM2");
    endcase
    state <= st;
end
endtask
endmodule


TestBench with hand assembled test program that increments a counter:
Code:
// One Page Challenge CPU Test Bench
// Hooks up a set of LEDS and a ROM for instructions

module OPCX_bench();
reg rst;
reg clk;
wire wr;
wire [31:0] adr;
wire [31:0] dato;
reg [31:0] dati;

reg [31:0] leds;

initial begin
    rst = 1'b0;
    clk = 1'b1;
    #10 rst = 1'b1;
    #40 rst = 1'b0;
end
always #5 clk = ~clk;

OPCX ucpu1
(
    .rst(rst),
    .clk(clk),
    .wr(wr),
    .adr(adr),
    .dato(dato),
    .dati(dati)
);

always @(posedge clk)
casex(adr)
32'hFFDC0600:   if (wr) leds <= dato;
32'hFFFC0000:   dati <= 32'b001000001000000001001;  // ORI r1,#1
32'hFFFC0004:   dati <= 32'b000000010000000001001;  // ORI r2,#0
32'hFFFC0008:   dati <= 32'hFFDC000F;               // immediate prefix
32'hFFFC000C:   dati <= 32'b00011000000000000010000000001101; // ST r2,$FFDC0600
32'hFFFC0010:   dati <= 32'b00010000_000010_000001_000010_000010; // ADD r2,r2,r1
32'hFFFC0014:   dati <= 32'b11111111110100_000000_000000_001011;    // BEQ r0,$FFFC0008
endcase

always @(posedge clk)
begin
    $display("PC: %h", ucpu1.pc);
    case(ucpu1.ir[5:0])
    6'h02:  begin
            $display("RR ");
            case(ucpu1.ir[31:26])
            6'h04:  $display("ADD ");
            endcase
            end
    6'h09:  $display("ORI ");
    6'h0B:  begin
            case(ucpu1.ir[17:12])
            6'h00:  $display("BEQ");
            endcase
            end
    6'h0D:  $display("ST  ");
    endcase
end

endmodule


You do not have the required permissions to view the files attached to this post.

_________________
Robert Finch http://www.finitron.ca


Fri Apr 28, 2017 9:23 pm WWW

Joined: Wed Apr 24, 2013 9:40 pm
Posts: 213
Location: Huntsville, AL
Rob:

I did not read in the challenge rules that you cannot take advantage of the capabilities of the Verilog parser and that the submission had to be readable. In addition, I did not see a definition of what the dimensions for a page or the type size. :D

Therefore, I suggest using the least legible point size for your printout, and take full advantage of the Verilog parser by removing all line breaks except those needed by the parser. A corollary is to combine parameter definitions in a single line as needed.

Mike

_________________
Michael A.


Fri Apr 28, 2017 10:31 pm

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2231
Location: Canada
I was very tempted to do just that, if I do that it will surely fit on one page. The core was only 130 lines by about 85 characters max with spaces and indents before it was split into separate files. If it were printed sideways on a 132 column page it would almost fit without having to scrunch it up.
However I can't stand unreadable code. I also likely want to expand on it at some point. There's no interrupts or mmu.
Given that one may place other components on individual pages (program memory, other memory, I/O) I don't think the one page challenge rules are badly broken.

Nobody prints out anything these days. Printing's nostalgic.

Other files (shows there isn't 1,000s of lines hidden aways somewhere):
IFETCH.vh
Code:
IFETCH1:    next_state(IFETCH2);
IFETCH2:
    begin
    regfile[Rt] <= |Rt ? res : {DBITS{1'b0}};
    ir <= dati;
    pc <= pc + 32'd4;
    adr <= pc + 32'd4;
    next_state(DECODE);
    end

DECODE.vh
Code:
DECODE:
    begin
    next_state(EXECUTE);
    a <= regfile[Ra];
    b <= regfile[Rb];
    if (immf)
        imm[11:0] <= ir[29:18];
    else
        imm <= {{18{ir[31]}},ir[31:18]};
    immf <= 1'b0;
    if (ir[5:0]==6'h0F) begin
        immf <= 1'b1;
        imm[31:12] <= ir[31:12];
        next_state(IFETCH1);
    end
    Rt <= ir[17:12];
    case(ir[5:0])
    6'h02:   Rt <= ir[23:18];
    6'h0B,6'h0D,6'h0F:   Rt <= 6'h0;
    endcase
    end

Execute.vh
Code:
EXECUTE:
    begin
    next_state(IFETCH1);
    case(ir[5:0])
    6'h02:
        case(ir[31:26])
        6'h00:  res <= {a,1'b0};
        6'h01:  res <= {1'b0,a[31:1]};
        6'h04:  res <= a + b;
        6'h05:  res <= a - b;
        6'h06:  res <= a < b ? -32'd1 : a==b ? 32'd0 : 32'd1;
        6'h08:  res <= a & b;
        6'h09:  res <= a | b;
        6'h0A:  res <= a ^ b;
        endcase
    6'h04:   res <= a + imm;
    6'h06:   res <= a < imm ? -32'd1 : a==imm ? 32'd0 : 32'd1;
    6'h08:   res <= a & imm;
    6'h09:   res <= a | imm;
    6'h0A:   res <= a ^ imm;
    6'h0B:
        case(ir[17:12])
        6'h00:   if (a==0) begin adr <= pc + imm; pc <= pc + imm; end
        6'h01:   if (a!=0) begin adr <= pc + imm; pc <= pc + imm; end
        6'h02:   if (!a[DBITS-1]) begin adr <= pc + imm; pc <= pc + imm; end
        6'h03:   if (a[DBITS-1]) begin adr <= pc + imm; pc <= pc + imm; end
        endcase
    6'h0C:   begin adr <= a + imm; next_state(MEM1); end
    6'h0D:   begin adr <= a + imm; dato <= b; wr <= 1'b1; next_state(MEM1); end
    6'h0E:   begin adr <= a + imm; res <= pc; pc <= a + imm; end
    endcase
    end

memory.vh
Code:
MEM1:  next_state(MEM2);
MEM2:
    begin
    res <= dati;
    adr <= pc;
    next_state(IFETCH1);
    end

_________________
Robert Finch http://www.finitron.ca


Fri Apr 28, 2017 11:06 pm WWW

Joined: Tue Jan 15, 2013 10:11 am
Posts: 114
Location: Norway/Japan
Ah, the days when I could (and did) print program listings in type 2.. or at least as small as 4. You could get anything into one page, almost.


Sat Apr 29, 2017 2:28 pm
 [ 108 posts ]  Go to page 1, 2, 3, 4, 5 ... 8  Next

Who is online

Users browsing this forum: CCBot, SemrushBot and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software