From 5371caa3bb018e8f4c6d65fbaa83c179c2e86126 Mon Sep 17 00:00:00 2001 From: "(Tim) Efthimis Kritikos" Date: Wed, 8 Feb 2023 23:59:06 +0000 Subject: [PATCH] Implemented a basic Instruction Fetch stage and added some examples in the 8086 doc --- .gitignore | 1 + 8086_documentation.md | 12 +++++++++++- cpu/boot_code.txt | 6 +++--- cpu/gtkwave_savefile.gtkw | 14 ++++++++------ cpu/processor.v | 22 +++++++++++----------- cpu/testbench.v | 4 +++- 6 files changed, 37 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index c1a8af5..6ac34cc 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.vpi *.lx2 *.o +*.swp diff --git a/8086_documentation.md b/8086_documentation.md index 5666c0d..50108e1 100644 --- a/8086_documentation.md +++ b/8086_documentation.md @@ -11,7 +11,7 @@ Instructions vary from 1 to 6 bytes. On some instructions: -* **S**-bit : An 8-bit 2’s complement number. It can be extended to a 16-bit 2’s complement number depending on the W-bit by making all of the bits in the higher-order byte equal the most significant bit in the low order byte. This is known as sign extension. +* **S**-bit : An 8-bit 2's complement number. It can be extended to a 16-bit 2’s complement number depending on the W-bit by making all of the bits in the higher-order byte equal the most significant bit in the low order byte. This is known as sign extension. | S | W | Operation | | --- | --- | -------------- | @@ -46,3 +46,13 @@ The second byte of the instruction usually identifies the instruction's operands |101 | [DI] | [DI] + d8 | [DI] + d16 | CH | BP | |110 | d16 (direct) | [BP] + d8 | [BP] + d16 | DH | SI | |111 | [BX] | [BX] + d8 | [BX] + d16 | BH | DI | + +Example instructions: + +| Bytecode | AT&T Syntax | meaning | +| ---------- | --------------- | ---------------------------------------------------------- | +|81 c0 aa 55 | add $0x55aa,%ax | write 0x55aa to register ax | +|03 06 aa 55 | add 0x55aa,%ax | write the contents of memory locaton 0x55aa to register ax | +|fe c0 | inc %al | increment register al | +|ff c0 | inc %ax | increment register ax | +|40 | inc %ax | increment register ax | diff --git a/cpu/boot_code.txt b/cpu/boot_code.txt index 7c34b60..d3a945c 100644 --- a/cpu/boot_code.txt +++ b/cpu/boot_code.txt @@ -1,7 +1,7 @@ // 0x00000000 -55AA -0000 -0000 +81C0 +AA55 +FEC0 0000 0000 0000 diff --git a/cpu/gtkwave_savefile.gtkw b/cpu/gtkwave_savefile.gtkw index e78cae2..9b2c765 100644 --- a/cpu/gtkwave_savefile.gtkw +++ b/cpu/gtkwave_savefile.gtkw @@ -1,13 +1,13 @@ [*] [*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI -[*] Wed Feb 8 11:44:52 2023 +[*] Wed Feb 8 23:43:14 2023 [*] [dumpfile] "/home/user/UNI_DATA/COMS30046_2022_TB-2/projects/9086/cpu/test.lx2" -[dumpfile_mtime] "Wed Feb 8 11:44:20 2023" -[dumpfile_size] 430 +[dumpfile_mtime] "Wed Feb 8 23:42:51 2023" +[dumpfile_size] 470 [savefile] "/home/user/UNI_DATA/COMS30046_2022_TB-2/projects/9086/cpu/gtkwave_savefile.gtkw" [timestart] 0 -[size] 1342 1059 +[size] 1534 1059 [pos] -1 -1 *-20.795050 2883000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 [treeopen] tb. @@ -19,12 +19,14 @@ tb.p.clock[0] tb.p.reset[0] tb.p.start[0] -tb.p.state[1:0] +@29 +tb.p.state[2:0] +@28 tb.p.instruction_finished[0] @22 tb.p.external_address_bus[19:0] tb.p.external_data_bus[15:0] -@29 +@28 tb.p.read[0] [pattern_trace] 1 [pattern_trace] 0 diff --git a/cpu/processor.v b/cpu/processor.v index b270d38..f6ef2dd 100644 --- a/cpu/processor.v +++ b/cpu/processor.v @@ -54,13 +54,13 @@ endmodule module processor ( input clock, input reset , output reg [19:0] external_address_bus, inout [15:0] external_data_bus,output reg read, output reg write); /* State */ -reg [1:0] state; +reg [2:0] state; reg start=0; reg instruction_finished; /* Registers */ reg [19:0] ProgCount; - +reg [14:0] CIR; /* RESET LOGIC */ always @(negedge reset) begin @@ -75,29 +75,29 @@ end /* CLOCK LOGIC */ always @(posedge clock) begin - if(instruction_finished) begin + if(instruction_finished) state =0; - end else begin - if (clock && start==1) begin + else + if (clock && start==1) state=state+1; - end - end end always @(state) begin - if (state==2) begin + if (state==5) instruction_finished=1; - end else begin + else instruction_finished=0; - end end /* Processor stages */ always @(state) begin - if (state==0) begin + if (state=='b000) begin external_address_bus <= ProgCount; read <= 0; write <= 1; + end else if ( state=='b001 ) begin + CIR <= external_data_bus; + ProgCount=ProgCount+1; end end diff --git a/cpu/testbench.v b/cpu/testbench.v index 3a8681d..c680966 100644 --- a/cpu/testbench.v +++ b/cpu/testbench.v @@ -9,6 +9,8 @@ wire rd,wr,romcs; processor p(clock,reset,address_bus,data_bus,rd,wr); rom bootrom(address_bus,data_bus,rd,romcs); +`define CPU_SPEED 1000 + clock_gen #(.FREQ(1000)) u1(clk_enable, clock); assign romcs=0; @@ -22,7 +24,7 @@ initial begin reset = 0; #(100) reset = 1; - #(10000) + #(`CPU_SPEED*30) #50 $finish; end