Conway works (with sleeps)
[clump.git] / chip.v
diff --git a/chip.v b/chip.v
index 610ad6fc333cdbf3bc9f743da6bc6bee6e254808..ff16cedd5ca796ae4e881ee7f5d643da3b6b8dca 100644 (file)
--- a/chip.v
+++ b/chip.v
@@ -7,22 +7,31 @@
 `define OP_ROUTE 3'd6
 `define OP_RUG   3'd7
 
+`define DIRECTION_N  3'd0
+`define DIRECTION_NE 3'd1
+`define DIRECTION_E  3'd2
+`define DIRECTION_SE 3'd3
+`define DIRECTION_S  3'd4
+`define DIRECTION_SW 3'd5
+`define DIRECTION_W  3'd6
+`define DIRECTION_NW 3'd7
+
 module chip(input clk, input [2:0] op, input [15:0] I, input io_pin, input CS, output reg [15:0] mem_in, input [15:0] mem_out, output reg mem_write);
 
    // parity is unimplemented
 
    // OP_LOADA
-   wire [2:0] flagr = I[2:0];
-   wire          bsel = I[3];
-   wire [7:0] aluc = I[11:4];
+   wire [3:0] flagr = I[3:0];
+   wire          bsel = I[4];
+   wire [0:7] aluc = I[12:5];
 
    // OP_LOADB
-   wire [2:0] cond = I[2:0];
-   wire          inv = I[3];
-   wire [7:0] alus = I[11:4];
+   wire [3:0] cond = I[3:0];
+   wire          inv = I[4];
+   wire [0:7] alus = I[12:5];
 
    // OP_STORE
-   wire [2:0] flagw = I[2:0];
+   wire [3:0] flagw = I[3:0];
    wire          edge_ = I[7];
    wire [3:0] cube = I[11:8];
 
@@ -40,101 +49,216 @@ module chip(input clk, input [2:0] op, input [15:0] I, input io_pin, input CS, o
    wire [4:0] reg_ = I[8:4];
 
 
-   reg [15:0] A;
-   reg [15:0] B;
-   reg [15:0] C;
-   reg [15:0] F;
-   reg [15:0] Cond;
-   reg [15:0] R;
-   reg [7:0]  alu_sum;
-   reg [7:0]  alu_carry;
+   reg [15:0] A = 0;
+   reg [15:0] B = 0;
+   reg [15:0] C = 0;
+   reg [15:0] F = 0;
+   reg [15:0] Cond = 0;
+   reg [15:0] R = 0;
+   reg [7:0]  alu_sum = 0;
+   reg [7:0]  alu_carry = 0;
    reg [15:0] cube_in;
    reg                   io;
 
    // these are not really regs
 
-   wire [15:0]  alu_sum_out;
-   wire [15:0]  alu_carry_out;
-
-   wire [2:0]  alu_index [15:0];
-
-assign alu_index[0] = (A[0] << 2) + (B[0] << 1) + F[0];
-assign alu_sum_out[0] = alu_sum[alu_index[0]];
-assign alu_carry_out[0] = alu_carry[alu_index[0]];
-assign alu_index[1] = (A[1] << 2) + (B[1] << 1) + F[1];
-assign alu_sum_out[1] = alu_sum[alu_index[1]];
-assign alu_carry_out[1] = alu_carry[alu_index[1]];
-assign alu_index[2] = (A[2] << 2) + (B[2] << 1) + F[2];
-assign alu_sum_out[2] = alu_sum[alu_index[2]];
-assign alu_carry_out[2] = alu_carry[alu_index[2]];
-assign alu_index[3] = (A[3] << 2) + (B[3] << 1) + F[3];
-assign alu_sum_out[3] = alu_sum[alu_index[3]];
-assign alu_carry_out[3] = alu_carry[alu_index[3]];
-assign alu_index[4] = (A[4] << 2) + (B[4] << 1) + F[4];
-assign alu_sum_out[4] = alu_sum[alu_index[4]];
-assign alu_carry_out[4] = alu_carry[alu_index[4]];
-assign alu_index[5] = (A[5] << 2) + (B[5] << 1) + F[5];
-assign alu_sum_out[5] = alu_sum[alu_index[5]];
-assign alu_carry_out[5] = alu_carry[alu_index[5]];
-assign alu_index[6] = (A[6] << 2) + (B[6] << 1) + F[6];
-assign alu_sum_out[6] = alu_sum[alu_index[6]];
-assign alu_carry_out[6] = alu_carry[alu_index[6]];
-assign alu_index[7] = (A[7] << 2) + (B[7] << 1) + F[7];
-assign alu_sum_out[7] = alu_sum[alu_index[7]];
-assign alu_carry_out[7] = alu_carry[alu_index[7]];
-assign alu_index[8] = (A[8] << 2) + (B[8] << 1) + F[8];
-assign alu_sum_out[8] = alu_sum[alu_index[8]];
-assign alu_carry_out[8] = alu_carry[alu_index[8]];
-assign alu_index[9] = (A[9] << 2) + (B[9] << 1) + F[9];
-assign alu_sum_out[9] = alu_sum[alu_index[9]];
-assign alu_carry_out[9] = alu_carry[alu_index[9]];
-assign alu_index[10] = (A[10] << 2) + (B[10] << 1) + F[10];
-assign alu_sum_out[10] = alu_sum[alu_index[10]];
-assign alu_carry_out[10] = alu_carry[alu_index[10]];
-assign alu_index[11] = (A[11] << 2) + (B[11] << 1) + F[11];
-assign alu_sum_out[11] = alu_sum[alu_index[11]];
-assign alu_carry_out[11] = alu_carry[alu_index[11]];
-assign alu_index[12] = (A[12] << 2) + (B[12] << 1) + F[12];
-assign alu_sum_out[12] = alu_sum[alu_index[12]];
-assign alu_carry_out[12] = alu_carry[alu_index[12]];
-assign alu_index[13] = (A[13] << 2) + (B[13] << 1) + F[13];
-assign alu_sum_out[13] = alu_sum[alu_index[13]];
-assign alu_carry_out[13] = alu_carry[alu_index[13]];
-assign alu_index[14] = (A[14] << 2) + (B[14] << 1) + F[14];
-assign alu_sum_out[14] = alu_sum[alu_index[14]];
-assign alu_carry_out[14] = alu_carry[alu_index[14]];
-assign alu_index[15] = (A[15] << 2) + (B[15] << 1) + F[15];
-assign alu_sum_out[15] = alu_sum[alu_index[15]];
-assign alu_carry_out[15] = alu_carry[alu_index[15]];
-
-   reg [2:0]   flags_addr;
+   reg [15:0]  alu_sum_out;
+   reg [15:0]  alu_carry_out;
+
+   reg [2:0]  alu_index [15:0];
+
+   reg [15:0]  idx;
 
    always @* begin
-         case(op)
-               `OP_LOADA:
-                 flags_addr <= flagr;
-               `OP_LOADB:
-                 flags_addr <= cond;
-               `OP_STORE:
-                 flags_addr <= flagw;
-               default:
-                 flags_addr <= 0;
-         endcase
+         for(idx = 0; idx < 16; idx=idx+1) begin
+                alu_index[idx] = (A[idx] << 2) + (B[idx] << 1) + F[idx];
+                alu_sum_out[idx] <= alu_sum[alu_index[idx]];
+                alu_carry_out[idx] <= alu_carry[alu_index[idx]];
+         end
    end
 
-   wire [15:0] flags_in;
-   reg  [15:0] flags_out;
+   reg [3:0] newstable[0:15][0:7];
+
+   initial begin
+         newstable[0][0] = 12;
+         newstable[0][1] = 13;
+         newstable[0][2] = 1;
+         newstable[0][3] = 5;
+         newstable[0][4] = 4;
+         newstable[0][5] = 7;
+         newstable[0][6] = 3;
+         newstable[0][7] = 15;
+         newstable[1][0] = 13;
+         newstable[1][1] = 14;
+         newstable[1][2] = 2;
+         newstable[1][3] = 6;
+         newstable[1][4] = 5;
+         newstable[1][5] = 4;
+         newstable[1][6] = 0;
+         newstable[1][7] = 12;
+         newstable[2][0] = 14;
+         newstable[2][1] = 15;
+         newstable[2][2] = 3;
+         newstable[2][3] = 7;
+         newstable[2][4] = 6;
+         newstable[2][5] = 5;
+         newstable[2][6] = 1;
+         newstable[2][7] = 13;
+         newstable[3][0] = 15;
+         newstable[3][1] = 12;
+         newstable[3][2] = 0;
+         newstable[3][3] = 4;
+         newstable[3][4] = 7;
+         newstable[3][5] = 6;
+         newstable[3][6] = 2;
+         newstable[3][7] = 14;
+         newstable[4][0] = 0;
+         newstable[4][1] = 1;
+         newstable[4][2] = 5;
+         newstable[4][3] = 9;
+         newstable[4][4] = 8;
+         newstable[4][5] = 11;
+         newstable[4][6] = 7;
+         newstable[4][7] = 3;
+         newstable[5][0] = 1;
+         newstable[5][1] = 2;
+         newstable[5][2] = 6;
+         newstable[5][3] = 10;
+         newstable[5][4] = 9;
+         newstable[5][5] = 8;
+         newstable[5][6] = 4;
+         newstable[5][7] = 0;
+         newstable[6][0] = 2;
+         newstable[6][1] = 3;
+         newstable[6][2] = 7;
+         newstable[6][3] = 11;
+         newstable[6][4] = 10;
+         newstable[6][5] = 9;
+         newstable[6][6] = 5;
+         newstable[6][7] = 1;
+         newstable[7][0] = 3;
+         newstable[7][1] = 0;
+         newstable[7][2] = 4;
+         newstable[7][3] = 8;
+         newstable[7][4] = 11;
+         newstable[7][5] = 10;
+         newstable[7][6] = 6;
+         newstable[7][7] = 2;
+         newstable[8][0] = 4;
+         newstable[8][1] = 5;
+         newstable[8][2] = 9;
+         newstable[8][3] = 13;
+         newstable[8][4] = 12;
+         newstable[8][5] = 15;
+         newstable[8][6] = 11;
+         newstable[8][7] = 7;
+         newstable[9][0] = 5;
+         newstable[9][1] = 6;
+         newstable[9][2] = 10;
+         newstable[9][3] = 14;
+         newstable[9][4] = 13;
+         newstable[9][5] = 12;
+         newstable[9][6] = 8;
+         newstable[9][7] = 4;
+         newstable[10][0] = 6;
+         newstable[10][1] = 7;
+         newstable[10][2] = 11;
+         newstable[10][3] = 15;
+         newstable[10][4] = 14;
+         newstable[10][5] = 13;
+         newstable[10][6] = 9;
+         newstable[10][7] = 5;
+         newstable[11][0] = 7;
+         newstable[11][1] = 4;
+         newstable[11][2] = 8;
+         newstable[11][3] = 12;
+         newstable[11][4] = 15;
+         newstable[11][5] = 14;
+         newstable[11][6] = 10;
+         newstable[11][7] = 6;
+         newstable[12][0] = 8;
+         newstable[12][1] = 9;
+         newstable[12][2] = 13;
+         newstable[12][3] = 1;
+         newstable[12][4] = 0;
+         newstable[12][5] = 3;
+         newstable[12][6] = 15;
+         newstable[12][7] = 11;
+         newstable[13][0] = 9;
+         newstable[13][1] = 10;
+         newstable[13][2] = 14;
+         newstable[13][3] = 2;
+         newstable[13][4] = 1;
+         newstable[13][5] = 0;
+         newstable[13][6] = 12;
+         newstable[13][7] = 8;
+         newstable[14][0] = 10;
+         newstable[14][1] = 11;
+         newstable[14][2] = 15;
+         newstable[14][3] = 3;
+         newstable[14][4] = 2;
+         newstable[14][5] = 1;
+         newstable[14][6] = 13;
+         newstable[14][7] = 9;
+         newstable[15][0] = 11;
+         newstable[15][1] = 8;
+         newstable[15][2] = 12;
+         newstable[15][3] = 0;
+         newstable[15][4] = 3;
+         newstable[15][5] = 2;
+         newstable[15][6] = 14;
+         newstable[15][7] = 10;
+   end // initial begin
+
+   reg [3:0] flags_addr_latch;
+   reg [3:0] flags_addr;
+
+   always @* begin
+         if(flags_addr_latch)
+               flags_addr <= flags_addr_latch;
+         else
+               case(op)
+                 `OP_LOADA:
+                       flags_addr <= flagr;
+                 `OP_LOADB:
+                       flags_addr <= cond;
+                 `OP_STORE:
+                       flags_addr <= flagw;
+                 default:
+                       flags_addr <= 0;
+               endcase
+   end // always @ *
+
+   reg  [15:0] flags_in;
+   wire [15:0] flags_out;
    reg                    flags_write;
 
-   RAM #(.ADDRESS_BITS(3)) flags (.clk(clk), .write(flags_write), .addr(flags_addr), .in(flags_in), .out(flags_out));
+   reg [15:0]  latest_news;
 
-   reg [15:0]  idx;
+   RAM #(.ADDRESS_BITS(3)) flags (.clk(clk), .write(flags_write), .addr(flags_addr[2:0]), .in(flags_in), .out(flags_out));
+
+   reg [15:0]  flag_or_news;
+
+   reg [15:0]  newsidx;
+
+   always @* begin
+         if(flags_addr[3]) begin // read from news
+                for(idx = 0; idx < 16; idx++) begin
+                       newsidx = newstable[idx][flags_addr[2:0]];
+                       flag_or_news[idx] = latest_news[newsidx];
+                end
+         end else begin
+                flag_or_news = flags_out;
+         end
+   end
 
    always @ (posedge clk) begin
          if(mem_write)
                mem_write <= 0;
-         if(flags_write)
-               flags_write <= 0;
+         if(flags_write) begin
+                flags_write <= 0;
+                flags_addr_latch <= 0;
+         end
 
          case (op)
                `OP_NOP: begin end
@@ -142,7 +266,7 @@ assign alu_carry_out[15] = alu_carry[alu_index[15]];
                `OP_LOADA:
                  begin
                         alu_carry <= aluc;
-                        F <= flags_out;
+                        F <= flag_or_news;
                         A <= mem_out;
                         C <= mem_out;
                         io <= io_pin;
@@ -153,19 +277,23 @@ assign alu_carry_out[15] = alu_carry[alu_index[15]];
                `OP_LOADB:
                  begin
                         alu_sum <= alus;
-                        Cond <= inv ? ~flags_out : flags_out;
+                        Cond <= inv ? ~flag_or_news : flag_or_news;
                         B <= mem_out;
                         R <= mem_out;
                  end
 
                `OP_STORE:
                  begin
-                        for(idx=0; idx < 16; idx++)
-                          flags_in[idx] <= Cond[idx] ? alu_carry_out[idx] : flags_out[idx];
-                        flags_write <= 1;
+                        for(idx = 0; idx < 16; idx++) begin
+                               flags_in[idx] = Cond[idx] ? alu_carry_out[idx] : flags_out[idx];
+                               latest_news[idx] <= flags_in[idx];
+                        end
+                        if(flags_addr) begin // we do not write to flag 0
+                               flags_write <= 1;
+                               flags_addr_latch <= flags_addr;
+                        end
                         mem_in <= alu_sum_out;
                         mem_write <= 1;
-                        // lots other stuff
                  end
 
                `OP_READ:
This page took 0.015788 seconds and 4 git commands to generate.