One Page Computing - roll your own challenge
Author |
Message |
BigEd
Joined: Wed Jan 09, 2013 6:54 pm Posts: 1783
|
. 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 |
|
![](./styles/serenity/theme/images/spacer.gif) |
MichaelM
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 |
|
![](./styles/serenity/theme/images/spacer.gif) |
Tor
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.. ![Smile :)](./images/smilies/icon_e_smile.gif) - 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 |
|
![](./styles/serenity/theme/images/spacer.gif) |
BigEd
Joined: Wed Jan 09, 2013 6:54 pm Posts: 1783
|
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 |
|
![](./styles/serenity/theme/images/spacer.gif) |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2095 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 ‘<>’ ![Smile :)](./images/smilies/icon_e_smile.gif) 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 |
|
![](./styles/serenity/theme/images/spacer.gif) |
BigEd
Joined: Wed Jan 09, 2013 6:54 pm Posts: 1783
|
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 |
|
![](./styles/serenity/theme/images/spacer.gif) |
MichaelM
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. ![Very Happy :D](./images/smilies/icon_e_biggrin.gif)
_________________ Michael A.
|
Wed Apr 26, 2017 1:57 am |
|
![](./styles/serenity/theme/images/spacer.gif) |
Dr Jefyll
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! ![Very Happy :D](./images/smilies/icon_e_biggrin.gif) 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. 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! ![Mr. Green :mrgreen:](./images/smilies/icon_mrgreen.gif) -- Jeff Attachment:
3200 State machine small.gif [ 49.98 KiB | Viewed 31102 times ]
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 [ 268.98 KiB | Viewed 31068 times ]
Attachments:
3200ACD.jpg [ 135.49 KiB | Viewed 31068 times ]
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 |
|
![](./styles/serenity/theme/images/spacer.gif) |
BigEd
Joined: Wed Jan 09, 2013 6:54 pm Posts: 1783
|
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.pdfRunning 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 |
|
![](./styles/serenity/theme/images/spacer.gif) |
Dr Jefyll
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. ![Smile :)](./images/smilies/icon_e_smile.gif)
|
Wed Apr 26, 2017 4:49 pm |
|
![](./styles/serenity/theme/images/spacer.gif) |
BigEd
Joined: Wed Jan 09, 2013 6:54 pm Posts: 1783
|
A photocopy - excellent! Thanks!
|
Wed Apr 26, 2017 5:01 pm |
|
![](./styles/serenity/theme/images/spacer.gif) |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2095 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:
File comment: Trace of OPCX incrementing counter
Presentation1.png [ 75.52 KiB | Viewed 31023 times ]
// 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
_________________Robert Finch http://www.finitron.ca
|
Fri Apr 28, 2017 9:23 pm |
|
![](./styles/serenity/theme/images/spacer.gif) |
MichaelM
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. 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 |
|
![](./styles/serenity/theme/images/spacer.gif) |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2095 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 |
|
![](./styles/serenity/theme/images/spacer.gif) |
Tor
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 |
|
|
Who is online |
Users browsing this forum: No registered users and 150 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
|
|