X-Git-Url: http://git.ieval.ro/?a=blobdiff_plain;f=chip.v;fp=chip.v;h=ff16cedd5ca796ae4e881ee7f5d643da3b6b8dca;hb=23c26e0422eda4cb868569e6c3cc4f41fe6e2864;hp=610ad6fc333cdbf3bc9f743da6bc6bee6e254808;hpb=5a2a82dc19c5d46c250c101202a43ee8375c2e28;p=clump.git diff --git a/chip.v b/chip.v index 610ad6f..ff16ced 100644 --- 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: