{"id":23586546,"url":"https://github.com/doctorwkt/simplecpu","last_synced_at":"2026-01-25T01:01:54.349Z","repository":{"id":96057467,"uuid":"179947554","full_name":"DoctorWkt/SimpleCPU","owner":"DoctorWkt","description":null,"archived":false,"fork":false,"pushed_at":"2019-04-07T13:18:12.000Z","size":24,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-13T14:50:56.560Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Verilog","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DoctorWkt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-07T10:06:04.000Z","updated_at":"2025-04-15T11:40:55.000Z","dependencies_parsed_at":null,"dependency_job_id":"aa11d9e5-74cb-40e1-b005-b5e3bd1697f2","html_url":"https://github.com/DoctorWkt/SimpleCPU","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/DoctorWkt/SimpleCPU","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DoctorWkt%2FSimpleCPU","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DoctorWkt%2FSimpleCPU/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DoctorWkt%2FSimpleCPU/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DoctorWkt%2FSimpleCPU/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DoctorWkt","download_url":"https://codeload.github.com/DoctorWkt/SimpleCPU/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DoctorWkt%2FSimpleCPU/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28740393,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T22:12:27.248Z","status":"ssl_error","status_checked_at":"2026-01-24T22:12:10.529Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-27T04:11:32.689Z","updated_at":"2026-01-25T01:01:54.323Z","avatar_url":"https://github.com/DoctorWkt.png","language":"Verilog","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SimpleCPU\n\nWarren's simple CPU. It's purpose is solely to help Warren understand\nhow to deal with block RAM/ROM which is clocked, as against RAM/ROM\nwhich is purely combinational. The high-level datapath design is:\n\n```\n                 8\n  ROM -----------/---------------------\n   ^        |        |        |       ^\n   |        V        V        V       |\n  8/        AR       IR       X-------+\n   |        |        |\n   |\u003c-------+        V\n   |              Decoder \u003c--- uSeq\n   V\n   PC\n```\n\nThe CPU is microsequenced. On phase zero of each high-level\ninstruction, IR is fetched from ROM[PC++] and uSeq is incremented.\nFurther phases can: load the address register (AR), load the X\nregister from ROM[PC] or ROM[AR], write the X register to ROM[AR],\nor write AR to PC (so as to jump the PC).\n\nThere are a few generic components: register, counter, memory.\nThe main ROM has 256 8-bit locations; ditto the Decoder ROM.\nThe low nibble of the IR is combined with the low nibble of the uSeq\nphase to index the Decoder ROM. Thus: only 16 possible high-level\ninstructions, each of which can have up to 16 microinstructions.\nThe current instructions are:\n\n```\n0 NOP: IRload PCincr         Do nothing except increment the PC\n       uSreset\n1 LCX: IRload PCincr         Load X with byte after instruction\n       Xload uSreset\n2 LDX: IRload PCincr         Load X with ROM[byte after instruction]\n       ARload PCincr\n       ARena Xload uSreset\n3 STX: IRload PCincr         Store X to ROM[byte after instruction]\n       ARload PCincr                 OK, so ROM is also RAM-like!\n       ARena Xena uSreset\n4 JMP: IRload PCincr         Jump: set PC's value to byte after instruction\n       ARload PCincr\n       ARena PCload uSreset\n```\n\nThe rom.hex file has this short machine code program:\n\n```\n  00: LCX $23        01 23\n  02: STX $40        03 40   Store 0x23 into memory location 0x40\n  04: LCX $56        01 56\n  06: STX $41        03 41   Store 0x56 into memory location 0x41\n  08: JMP $0C        04 0C   Skip over some instructions\n  0A: NOP            00\n  0B: NOP            00\n  0C: LDX $40        02 40   Load X from mem location 0x40, should get 0x23\n  0E: LDX $41        02 41   Load X from mem location 0x41, should get 0x56\n  10: NOP            00\n  11: JMP $10        04 10   Jump back to the NOP at location 0x10\n```\n## Update: Fixed the Problem\n\nI was able to convert my memory module into a clocked version:\n\n```\n  output reg [7:0] result;      // Output memory's value\n  reg [7:0] mem [0:255];        // Actual memory store\n  always @(posedge i_clk) begin // Update internal value if wr_stb is high\n    if (wr_stb)\n      mem[address] \u003c= data;\n    result \u003c= mem[address];     // Update result on each clock tick\n  end\n```\nTo get the CPU to deal with the change, I changed the microsequences to provide\nsome delays to give the memory ROM and Decode ROM time to propagate their outputs.\nBelow are the new microsequences. The starred lines indicate the changes made.\n\n```\n0 NOP: IRload PCincr            Increment the PC, load the IR\n       * do_nothing             (wait for the IR to be loaded)\n       uSreset                  Reset the micosequencer\n\n1 LCX: IRload PCincr            Increment the PC, load the IR\n       * do_nothing             (wait for the IR to be loaded)\n       Xload uSreset            Load the X register, reset the micosequencer\n\n2 LDX: IRload PCincr            Increment the PC, load the IR\n       * do_nothing             (wait for the IR to be loaded)\n       ARload PCincr            Load the address reg, increment the PC\n       * Arena                  Use the AR to index the ROM, wait for it\n       Xload uSreset            Load the X register, reset the micosequencer\n\n3 STX: IRload PCincr            Increment the PC, load the IR\n       * do_nothing             (wait for the IR to be loaded)\n       ARload PCincr            Load the address reg, increment the PC\n       ARena Xena uSreset       Put X on the databus, write to ROM, reset uSeq\n\n4 JMP: IRload PCincr            Increment the PC, load the IR\n       * do_nothing             (wait for the IR to be loaded)\n       ARload                   Load the address register\n       ARena PCload uSreset     Load the PC from AR, reset the micosequencer\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoctorwkt%2Fsimplecpu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdoctorwkt%2Fsimplecpu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoctorwkt%2Fsimplecpu/lists"}