From 39f55aa6c3d0e91849d421e39487ff41cfaa5d94 Mon Sep 17 00:00:00 2001 From: "(Tim) Efthimis Kritikos" Date: Fri, 10 Feb 2023 12:02:20 +0000 Subject: [PATCH] Added unaligned access for instructions and data and fixed register file access --- cpu/boot_code.txt | 26 ++++++++--------- cpu/proc_state_def.v | 18 +++++++----- cpu/processor.v | 66 +++++++++++++++++++++++++++++++++++++++----- cpu/registers.v | 5 ++-- cpu/testbench.v | 2 +- 5 files changed, 86 insertions(+), 31 deletions(-) diff --git a/cpu/boot_code.txt b/cpu/boot_code.txt index d3a945c..34b8023 100644 --- a/cpu/boot_code.txt +++ b/cpu/boot_code.txt @@ -1,17 +1,17 @@ // 0x00000000 -81C0 -AA55 +05AA +55FE +C0FE +C0FE +C005 +EF41 FEC0 +0500 +05FE +C081 +C1AA +5505 0000 -0000 -0000 -0000 -0000 -0000 -0000 -0000 -0000 -0000 -0000 -0000 +81C2 +BEEF 0000 diff --git a/cpu/proc_state_def.v b/cpu/proc_state_def.v index 2b56942..708fb83 100644 --- a/cpu/proc_state_def.v +++ b/cpu/proc_state_def.v @@ -1,13 +1,17 @@ -`define PROC_HALT_STATE 4'b0000 +`define PROC_HALT_STATE 4'b0000 /*INSTRUCTION FETCH STATE*/ -`define PROC_IF_STATE_ENTRY 4'b0001 -`define PROC_IF_WRITE_CIR 4'b0010 +`define PROC_IF_STATE_ENTRY 4'b0001 +`define PROC_IF_WRITE_CIR 4'b0010 +`define PROC_IF_STATE_EXTRA_FETCH_SET 4'b0011 +`define PROC_IF_STATE_EXTRA_FETCH 4'b1111 /******/ /*DECODE SATE*/ -`define PROC_DE_STATE_ENTRY 4'b0100 -`define PROC_DE_LOAD_16_PARAM 4'b0101 +`define PROC_DE_STATE_ENTRY 4'b0100 +`define PROC_DE_LOAD_16_PARAM 4'b0101 +`define PROC_DE_LOAD_16_EXTRA_FETCH_SET 4'b0110 +`define PROC_DE_LOAD_16_EXTRA_FETCH 4'b0111 /*EXECUTE STATE*/ -`define PROC_EX_STATE_ENTRY 4'b1000 -`define PROC_EX_STATE_EXIT 4'b1001 +`define PROC_EX_STATE_ENTRY 4'b1000 +`define PROC_EX_STATE_EXIT 4'b1001 diff --git a/cpu/processor.v b/cpu/processor.v index 93d3707..c669f1e 100644 --- a/cpu/processor.v +++ b/cpu/processor.v @@ -22,6 +22,7 @@ reg [19:0] ProgCount; reg [15:0] CIR; reg [15:0] PARAM1; reg [15:0] PARAM2; +reg unaligned_access; // Execution units reg [1:0] in1_sel; @@ -38,6 +39,7 @@ always @(negedge reset) begin reg_read=1; reg_write=1; reg_read_read=1; + unaligned_access=0; ALU_OUT=1; @(negedge clock); @(posedge clock); @@ -90,9 +92,18 @@ ADDER16 ADDER16_1(ADDER16_1A,ADDER16_1B,ALU_OUT,ADDER16_1O,ADDER16_1C); always @(negedge clock) begin case(state) `PROC_IF_WRITE_CIR:begin - CIR <= external_data_bus; - ProgCount=ProgCount+1; - state=`PROC_DE_STATE_ENTRY; + if(unaligned_access)begin + CIR[15:8] <= external_data_bus[7:0]; + ProgCount=ProgCount+1; + state=`PROC_IF_STATE_EXTRA_FETCH_SET; + end else begin + CIR <= external_data_bus; + state=`PROC_DE_STATE_ENTRY; + end + end + `PROC_IF_STATE_EXTRA_FETCH:begin + CIR[7:0] <= external_data_bus[15:8]; + state=`PROC_DE_STATE_ENTRY; end `PROC_EX_STATE_EXIT:begin case(out_sel) @@ -104,6 +115,10 @@ always @(negedge clock) begin endcase state=`PROC_IF_STATE_ENTRY; end + `PROC_DE_LOAD_16_EXTRA_FETCH_SET:begin + external_address_bus = ProgCount; + state=`PROC_DE_LOAD_16_EXTRA_FETCH; + end endcase end @@ -123,14 +138,38 @@ always @(posedge clock) begin ALU_OUT=1; state=`PROC_IF_WRITE_CIR; end + `PROC_IF_STATE_EXTRA_FETCH_SET:begin + external_address_bus <= ProgCount; + state=`PROC_IF_STATE_EXTRA_FETCH; + end `PROC_DE_STATE_ENTRY:begin - external_address_bus <= ProgCount; /*Remenance from IF*/ case(CIR[15:10]) + 6'b000001 : begin + /* ADD, ... */ + if ( CIR[9:9] == 0 )begin + /* Add Immediate to accumulator */ + unaligned_access=~unaligned_access; + in1_sel=2'b00; + in2_sel=2'b01; + out_sel=2'b01; + reg_read_addr=3'b000; + reg_addr=3'b000; + reg_read_read=0; + ALU_OUT=0; + state=`PROC_DE_LOAD_16_PARAM; + end else begin + `invalid_instruction + end + end 6'b100000 : begin /* ADD, ADC, SUB, SBB, CMP , AND, ... */ case (CIR[5:3]) 3'b000 : begin /* Add Immediate to register/memory */ + if(unaligned_access==0)begin + ProgCount=ProgCount+1; + external_address_bus <= ProgCount; + end in1_sel=2'b00; in2_sel=2'b01; out_sel=2'b01; @@ -151,6 +190,10 @@ always @(posedge clock) begin case (CIR[5:3]) 3'b000 :begin /* Increment Register or Memmory */ + if(unaligned_access==0)begin + ProgCount=ProgCount+1; + external_address_bus <= ProgCount; + end in1_sel=2'b00; in2_sel=2'b01; out_sel=2'b01; @@ -175,15 +218,24 @@ always @(posedge clock) begin endcase end `PROC_DE_LOAD_16_PARAM:begin - PARAM1 <= external_data_bus; - ProgCount=ProgCount+1; + if(unaligned_access==1)begin + PARAM1[15:8] = external_data_bus[7:0]; + ProgCount=ProgCount+1; + state=`PROC_DE_LOAD_16_EXTRA_FETCH_SET; + end else begin + PARAM1 <= external_data_bus; + ProgCount=ProgCount+1; + state=`PROC_EX_STATE_ENTRY; + end + end + `PROC_DE_LOAD_16_EXTRA_FETCH:begin + PARAM1[7:0] = external_data_bus[15:8]; state=`PROC_EX_STATE_ENTRY; end `PROC_EX_STATE_ENTRY:begin reg_data=ADDER16_1O; state=`PROC_EX_STATE_EXIT; EXCEPTION=0; - end endcase end diff --git a/cpu/registers.v b/cpu/registers.v index 0e6d470..ae55edb 100644 --- a/cpu/registers.v +++ b/cpu/registers.v @@ -1,8 +1,7 @@ module register_file ( input [2:0]addr1, inout [15:0]data1, input wire read1, input wire write1 ,input [2:0]addr2,output [15:0]data2,input wire read2); reg [15:0] registers [7:0]; -assign data2 = !read2 ? registers[0] : 'hz ; -//assign data2 = !read2 ? registers[addr2]: 'b1111000011110000; -assign data1 = !read1 ? registers[addr1]: 'hz; +assign data2 = !read2 ? registers[addr2] : 'hz; +assign data1 = !read1 ? registers[addr1] : 'hz; initial begin registers['b000]=0; registers['b001]=0; diff --git a/cpu/testbench.v b/cpu/testbench.v index 7a8d9fc..119e683 100644 --- a/cpu/testbench.v +++ b/cpu/testbench.v @@ -26,7 +26,7 @@ initial begin reset = 0; #(`CPU_SPEED) reset = 1; - #(`CPU_SPEED*30) + #(`CPU_SPEED*55) //$writememh("register_dump.txt", registers); #50 $finish;