worker/master split
authorMarius Gavrilescu <marius@ieval.ro>
Sat, 2 Mar 2019 19:42:50 +0000 (19:42 +0000)
committerMarius Gavrilescu <marius@ieval.ro>
Sat, 2 Mar 2019 19:42:50 +0000 (19:42 +0000)
asm.pm
chip.v
master.v [new file with mode: 0644]
master_rom.v [new file with mode: 0644]
news.v [new file with mode: 0644]
newstable.pl
ram.v
toplevel.v
worker.v [new file with mode: 0644]

diff --git a/asm.pm b/asm.pm
index d07004e5cc6cf65e78b1c42c7dfc617826b170bb..492bfccc1e2764dce4e1a4c0f20a3f615a17e854 100644 (file)
--- a/asm.pm
+++ b/asm.pm
@@ -102,6 +102,7 @@ sub loadi {
 }
 
 sub flag_zero { 0 }
+sub flag_temp { 7 }
 
 sub flag_news { 8 + $_[0] }
 
@@ -172,3 +173,57 @@ sub addC {
        my ($addrA, $addrB, $addrC, $flag_carry) = @_;
        alu3 aluc_add, alus_add, $addrA, $addrB, $addrC, $flag_carry, $flag_carry;
 }
+
+# news_gen face partea de mijloc
+# news_[mf][mf] face primul alu3, apeleaza news_gen, apoi face ultimul alu3
+sub news_generic {
+       my ($nX, $nY, $dest) = @_;
+       my %dest = %$dest;
+       while ($nX || $nY) {
+               my $direction;
+               if ($nX && $nY) {
+                       $nX--;
+                       $nY--;
+                       $direction = 7;
+               } elsif ($nX) {
+                       $nX--;
+                       $direction = 0;
+               } else {
+                       $nY--;
+                       $direction = 6;
+               }
+               if ($nX || $nY) { # not the last go
+                       alu3 alu_select_f, alu_select_a, 0, 0, 0, flag_news($direction), flag_zero
+               } elsif (exists $dest{address}) {
+                       alu3 alu_select_f, alu_select_f, 0, 0, $dest{address}, flag_news($direction), flag_zero
+               } elsif (exists $dest{flag}) {
+                       alu3 alu_select_f, alu_select_a, 0, 0, 0, flag_news($direction), $dest{flag}
+               } else {
+                       die "No destination address nor flag given to [news_generic]\n"
+               }
+       }
+}
+
+sub news_mm {
+       my ($addrIN, $addrOUT, $nX, $nY) = @_;
+       alu3 alu_select_a, alu_select_a, $addrIN, 0, $addrIN, flag_zero, flag_zero;
+       news_generic $nX, $nY, {address => $addrOUT};
+}
+
+sub news_mf {
+       my ($addrIN, $flagOUT, $nX, $nY) = @_;
+       alu3 alu_select_a, alu_select_a, $addrIN, 0, $addrIN, flag_zero, flag_zero;
+       news_generic $nX, $nY, {flag => $flagOUT};
+}
+
+sub news_fm {
+       my ($flagIN, $addrOUT, $nX, $nY) = @_;
+       alu3 alu_select_f, alu_select_a, 0, 0, 0, $flagIN, flag_zero;
+       news_generic $nX, $nY, {address => $addrOUT};
+}
+
+sub news_ff {
+       my ($flagIN, $flagOUT, $nX, $nY) = @_;
+       alu3 alu_select_f, alu_select_a, 0, 0, 0, $flagIN, flag_zero;
+       news_generic $nX, $nY, {flag => $flagOUT};
+}
diff --git a/chip.v b/chip.v
index ff16cedd5ca796ae4e881ee7f5d643da3b6b8dca..b29fde674e49645d41ad06993427028e448a4612 100644 (file)
--- a/chip.v
+++ b/chip.v
@@ -1,3 +1,5 @@
+`include "news.v"
+
 `define OP_NOP   3'd0
 `define OP_LOADA 3'd1
 `define OP_LOADB 3'd2
@@ -16,7 +18,7 @@
 `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);
+module chip(input clk, input [2:0] op, input [15:0] I, input io_pin, input CS, output reg [63:0] mem_in, input [63:0] mem_out, output reg mem_write);
 
    // parity is unimplemented
 
@@ -49,167 +51,34 @@ 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 = 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 [63:0] A = 0;
+   reg [63:0] B = 0;
+   reg [63:0] C = 0;
+   reg [63:0] F = 0;
+   reg [63:0] Cond = 0;
+   reg [63:0] R = 0;
    reg [7:0]  alu_sum = 0;
    reg [7:0]  alu_carry = 0;
-   reg [15:0] cube_in;
+   reg [63:0] cube_in;
    reg                   io;
 
    // these are not really regs
 
-   reg [15:0]  alu_sum_out;
-   reg [15:0]  alu_carry_out;
+   reg [63:0]  alu_sum_out;
+   reg [63:0]  alu_carry_out;
 
-   reg [2:0]  alu_index [15:0];
+   reg [2:0]  alu_index [63:0];
 
    reg [15:0]  idx;
 
    always @* begin
-         for(idx = 0; idx < 16; idx=idx+1) begin
+         for(idx = 0; idx < 64; 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
 
-   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;
 
@@ -229,28 +98,20 @@ module chip(input clk, input [2:0] op, input [15:0] I, input io_pin, input CS, o
                endcase
    end // always @ *
 
-   reg  [15:0] flags_in;
-   wire [15:0] flags_out;
+   reg  [63:0] flags_in;
+   wire [63:0] flags_out;
    reg                    flags_write;
 
-   reg [15:0]  latest_news;
+   reg [63:0]  latest_news;
 
    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 [63:0]  flag_or_news;
+   reg [63:0]  news_out;
 
-   reg [15:0]  newsidx;
+   news newspaper (.news_in(latest_news), .direction(flags_addr[1:0]), .news_out(news_out));
 
-   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
+   assign flag_or_news = flags_addr[3] ? news_out : flags_out;
 
    always @ (posedge clk) begin
          if(mem_write)
@@ -284,7 +145,7 @@ module chip(input clk, input [2:0] op, input [15:0] I, input io_pin, input CS, o
 
                `OP_STORE:
                  begin
-                        for(idx = 0; idx < 16; idx++) begin
+                        for(idx = 0; idx < 64; idx++) begin
                                flags_in[idx] = Cond[idx] ? alu_carry_out[idx] : flags_out[idx];
                                latest_news[idx] <= flags_in[idx];
                         end
diff --git a/master.v b/master.v
new file mode 100644 (file)
index 0000000..0057388
--- /dev/null
+++ b/master.v
@@ -0,0 +1,80 @@
+`include "master_rom.v"
+
+`ifdef SIM
+ `define UART_DIVIDE 1
+`else
+ `define UART_DIVIDE 1
+ // s/192/3/ for 19200 baud uart
+`endif
+
+module master(input CLKin, output [4:0] led, output uart_tx, input uart_rx, output reg ready_out = 1, input ready_in);
+   wire clk;
+   wire clk_tmp;
+
+   //pll pll (.clock_in(CLKin), .clock_out(clk));
+
+   reg [20:0] counter = 0;
+
+   reg                   clk = 0;
+
+   always @ (posedge CLKin) begin
+         if(counter == 5000) begin
+                counter <= 0;
+                clk <= 1 - clk;
+         end
+         else
+               counter <= counter + 1;
+   end
+
+   reg [4:0] program_counter = 0;
+   wire [63:0] rom_output;
+
+   master_rom master_rom (.clk(clk), .addr(program_counter), .data(rom_output));
+
+
+`define STATE_SEND 0
+`define STATE_WAIT_PROPAGATE 1
+`define STATE_WAIT_NEWS 2
+
+   reg [5:0] state = `STATE_SEND;
+   reg [5:0] uart_ptr = 0;
+
+   wire           received;
+   wire [7:0]  rx_byte;
+   reg                    transmit = 0;
+   reg  [7:0]  tx_byte = 0;
+   wire           is_receiving;
+   wire           is_transmitting;
+
+   // 19200 (actually 300) baud uart
+   uart #(.CLOCK_DIVIDE(`UART_DIVIDE)) uart (.clk(clk), .rx(uart_rx), .tx(uart_tx), .received(received), .transmit(transmit), .tx_byte(tx_byte), .rx_byte(rx_byte), .is_receiving(is_receiving), .is_transmitting(is_transmitting));
+
+   always @(posedge clk) begin
+         case(state)
+               `STATE_SEND: begin
+                  if(transmit) begin
+                         transmit <= 0;
+                  end else if(uart_ptr == 4) begin
+                         program_counter <= program_counter + 1;
+                         uart_ptr <= 0;
+                         state <= `STATE_WAIT_PROPAGATE;
+                  end else if(!is_transmitting && ready_in) begin
+                         tx_byte <= rom_output[uart_ptr * 8 +: 8];
+                         transmit <= 1;
+                         uart_ptr <= uart_ptr + 1;
+                  end
+               end
+
+               `STATE_WAIT_PROPAGATE: begin
+                  if(received) begin
+                         state <= `STATE_SEND;
+                  end
+               end
+
+               `STATE_WAIT_NEWS: begin
+
+               end
+         endcase
+   end
+
+endmodule
diff --git a/master_rom.v b/master_rom.v
new file mode 100644 (file)
index 0000000..f950628
--- /dev/null
@@ -0,0 +1,26 @@
+// ROM module with single input addr, output port, and clock input.
+// Data is clocked out of the ROM on positive clock edges.
+
+module master_rom (input clk, input [3:0] addr, output reg [63:0] data);
+   always @ (posedge clk) begin
+      case(addr)
+               4'd0:    data <= 8'b0001_0110; // LDI 6
+               4'd1:    data <= 8'b0110_0010; // JP 9
+               4'd2:    data <= 8'b0010_0001; // ADD 1
+               4'd3:    data <= 8'b1001_0000; // WRITE
+               4'd4:    data <= 8'b0110_0010; // JP 2
+               4'd5:    data <= 8'b0000_0000;
+               4'd6:    data <= 8'b0001_0001; // LDI 1
+               4'd7:    data <= 8'b1000_0000; // READ
+               4'd8:    data <= 8'b0110_0111; // JP 7
+               4'd9:    data <= 8'b1110_0000; // LDQ
+               4'd10:   data <= 8'b0001_1100; // LDI 12
+               4'd11:   data <= 8'b1010_0000; // CONS
+               4'd12:   data <= 8'b1100_0000; // RDQ
+               4'd13:   data <= 8'b1101_0000; // CDR
+               4'd14:   data <= 8'b1100_0000; // RDQ
+               4'd15:   data <= 8'b0000_0000;
+               default: data <= 8'bxxxx_xxxx;
+         endcase
+   end
+endmodule
diff --git a/news.v b/news.v
new file mode 100644 (file)
index 0000000..d2e1def
--- /dev/null
+++ b/news.v
@@ -0,0 +1,11 @@
+module news(input clk, input [63:0] news_in, input [1:0] direction, output [63:0] news_out);
+   always @(posedge clk) begin
+                case (direction)
+                  0: news_out = {news_in[56:63], news_in[0:55]};
+                  1: news_out = {news_in[ 1], news_in[ 2], news_in[ 3], news_in[ 4], news_in[ 5], news_in[ 6], news_in[ 7], news_in[ 0], news_in[ 9], news_in[10], news_in[11], news_in[12], news_in[13], news_in[14], news_in[15], news_in[ 8], news_in[17], news_in[18], news_in[19], news_in[20], news_in[21], news_in[22], news_in[23], news_in[16], news_in[25], news_in[26], news_in[27], news_in[28], news_in[29], news_in[30], news_in[31], news_in[24], news_in[33], news_in[34], news_in[35], news_in[36], news_in[37], news_in[38], news_in[39], news_in[32], news_in[41], news_in[42], news_in[43], news_in[44], news_in[45], news_in[46], news_in[47], news_in[40], news_in[49], news_in[50], news_in[51], news_in[52], news_in[53], news_in[54], news_in[55], news_in[48], news_in[57], news_in[58], news_in[59], news_in[60], news_in[61], news_in[62], news_in[63], news_in[56]};
+                  2: news_out = {news_in[ 8], news_in[ 9], news_in[10], news_in[11], news_in[12], news_in[13], news_in[14], news_in[15], news_in[16], news_in[17], news_in[18], news_in[19], news_in[20], news_in[21], news_in[22], news_in[23], news_in[24], news_in[25], news_in[26], news_in[27], news_in[28], news_in[29], news_in[30], news_in[31], news_in[32], news_in[33], news_in[34], news_in[35], news_in[36], news_in[37], news_in[38], news_in[39], news_in[40], news_in[41], news_in[42], news_in[43], news_in[44], news_in[45], news_in[46], news_in[47], news_in[48], news_in[49], news_in[50], news_in[51], news_in[52], news_in[53], news_in[54], news_in[55], news_in[56], news_in[57], news_in[58], news_in[59], news_in[60], news_in[61], news_in[62], news_in[63], news_in[ 0], news_in[ 1], news_in[ 2], news_in[ 3], news_in[ 4], news_in[ 5], news_in[ 6], news_in[ 7]};
+                  3: news_out = {news_in[ 7], news_in[ 0], news_in[ 1], news_in[ 2], news_in[ 3], news_in[ 4], news_in[ 5], news_in[ 6], news_in[15], news_in[ 8], news_in[ 9], news_in[10], news_in[11], news_in[12], news_in[13], news_in[14], news_in[23], news_in[16], news_in[17], news_in[18], news_in[19], news_in[20], news_in[21], news_in[22], news_in[31], news_in[24], news_in[25], news_in[26], news_in[27], news_in[28], news_in[29], news_in[30], news_in[39], news_in[32], news_in[33], news_in[34], news_in[35], news_in[36], news_in[37], news_in[38], news_in[47], news_in[40], news_in[41], news_in[42], news_in[43], news_in[44], news_in[45], news_in[46], news_in[55], news_in[48], news_in[49], news_in[50], news_in[51], news_in[52], news_in[53], news_in[54], news_in[63], news_in[56], news_in[57], news_in[58], news_in[59], news_in[60], news_in[61], news_in[62]};
+                endcase
+
+   end
+endmodule
index 402de4f33aaf4e9077476e04c1e0aa5a75a30631..233d317e1f660fcc3b97a432dd4204ec8594fb89 100644 (file)
@@ -4,18 +4,20 @@ use warnings;
 
 my @diffs = (
        [-1,  0],
-       [-1,  1],
+#      [-1,  1],
        [0 ,  1],
-       [1 ,  1],
+#      [1 ,  1],
        [1 ,  0],
-       [1 , -1],
+#      [1 , -1],
        [0 , -1],
-       [-1, -1]
+#      [-1, -1]
 );
 
 my @cpus;
 
-my $side = 4; # there are $side * $side CPUs
+my @newstable;
+
+my $side = 8; # there are $side * $side CPUs
 
 for my $line (0 .. ($side - 1)) {
        $cpus[$line] = [ ($line * $side) .. (($line + 1) * $side - 1) ]
@@ -24,9 +26,18 @@ for my $line (0 .. ($side - 1)) {
 for my $cpu (0 .. ($side * $side - 1)) {
        my $x = $cpu / $side;
        my $y = $cpu % $side;
-       for my $direction (0 .. 7) {
+       for my $direction (0 .. $#diffs) {
                my $nx = ($x + $diffs[$direction][0] + $side) % $side;
                my $ny = ($y + $diffs[$direction][1] + $side) % $side;
-               say "newstable[$cpu][$direction] = ", $cpus[$nx][$ny], ';';
+               $newstable[$cpu][$direction] = $cpus[$nx][$ny];
+       }
+}
+
+for my $direction (0 .. $#diffs) {
+       print "$direction: flag_or_news = {";
+       printf 'latest_news[%2d]', $newstable[0][$direction];
+       for my $cpu (1 .. ($side * $side - 1)) {
+               printf ', latest_news[%2d]', $newstable[$cpu][$direction];
        }
+       say '};'
 }
diff --git a/ram.v b/ram.v
index acd11eeb1613e592e4058f5366cc09d25ccece71..28e0f06e255e12f126c4c0656f3d270b387076aa 100644 (file)
--- a/ram.v
+++ b/ram.v
@@ -1,7 +1,7 @@
 module RAM #(parameter ADDRESS_BITS = 4)
-(input clk, input write, input[ADDRESS_BITS-1:0] addr, input [15:0] in, output reg [15:0] out);
+(input clk, input write, input[ADDRESS_BITS-1:0] addr, input [63:0] in, output reg [63:0] out);
 
-    reg [15:0] memory [0:2**ADDRESS_BITS-1];
+    reg [63:0] memory [0:2**ADDRESS_BITS-1];
 
    reg [ADDRESS_BITS:0] idx;
    initial begin
index f9082347b93abe6ee5236be4380a63e5b3e5b6ff..5939ffefda035d438d6e385ec89e0e6a08536726 100644 (file)
-`include "pll.v"
-`include "ram.v"
-`include "chip.v"
-`include "uart.v"
+`include "master.v"
+`include "worker.v"
 
-`ifdef SIM
- `define UART_DIVIDE 1
-`else
- `define UART_DIVIDE 1
- // s/192/3/ for 19200 baud uart
-`endif
+module toplevel (input CLKin, output [4:0] led);
+   wire worker_tx;
+   wire worker_rx;
 
-module toplevel (input CLKin, output [4:0] led, output uart_tx, input uart_rx);
-   wire clk;
-   wire clk_tmp;
+   wire worker_ready;
+   wire master_ready;
 
-   //pll pll (.clock_in(CLKin), .clock_out(clk));
+   wire [4:0] worker_led;
+   wire [4:0] master_led;
 
-   reg [20:0] counter = 0;
+   worker worker (.CLKin(CLKin), .led(worker_led), .uart_tx(worker_tx), .uart_rx(worker_rx), .ready_out(worker_ready), .ready_in(master_ready));
 
-   reg                   clk = 0;
+   master master (.CLKin(CLKin), .led(master_led), .uart_tx(worker_rx), .uart_rx(worker_tx), .ready_out(master_ready), .ready_in(worker_ready));
 
-   always @ (posedge CLKin) begin
-         if(counter == 5000) begin
-                counter <= 0;
-                clk <= 1 - clk;
-         end
-         else
-               counter <= counter + 1;
-   end
-
-   wire [11:0] mem_addr;
-   wire [15:0] mem_in;
-   wire [15:0] mem_out;
-   wire           mem_write;
-
-   RAM #(.ADDRESS_BITS(8)) ram (.clk(clk), .write(mem_write), .addr(mem_addr), .in(mem_in), .out(mem_out));
-
-   reg [7:0]   from_uart [3:0];
-   reg [2:0]   uart_ptr = 0;
-
-   wire [15:0] I  = {from_uart[1], from_uart[0]};
-   assign mem_addr = from_uart[2];
-   wire [2:0]  op_from_uart = from_uart[3][2:0];
-   wire           CS = from_uart[3][3];
-
-   reg [2:0]   op = 0;
-
-   reg [2:0]   last_op = 0;
-
-   reg [15:0]  I;
-   reg                    CS;
-
-   chip chip (.clk(clk), .op(op), .I(I), .io_pin(0), .CS(CS), .mem_in(mem_in), .mem_out(mem_out), .mem_write(mem_write));
-
-   wire           received;
-   wire [7:0]  rx_byte;
-   reg                    transmit = 0;
-   reg  [7:0]  tx_byte = 0;
-   wire           is_receiving;
-   wire           is_transmitting;
-
-   // 19200 (actually 300) baud uart
-   uart #(.CLOCK_DIVIDE(`UART_DIVIDE)) uart (.clk(clk), .rx(uart_rx), .tx(uart_tx), .received(received), .transmit(transmit), .tx_byte(tx_byte), .rx_byte(rx_byte), .is_receiving(is_receiving), .is_transmitting(is_transmitting));
-
-   assign led[0] = is_transmitting;
-   assign led[4] = received;
-//   assign led[3:1] = last_op;
-
-   reg                    did_it = 0;
-   assign led[2] = did_it;
-
-   reg [2:0]   state = 0;
-
-//   assign led[4:2] = state;
-
-   always @ (posedge clk) begin
-         if (state == 0 && received) begin
-                from_uart[uart_ptr] <= rx_byte;
-                uart_ptr <= uart_ptr + 1;
-         end
-
-         if (state == 0 && uart_ptr == 4) begin
-                op <= op_from_uart;
-                last_op <= op_from_uart;
-                uart_ptr <= 0;
-                did_it <= 1;
-                state <= 1;
-         end
-
-         if (state == 1 && op != `OP_READ) begin
-                op <= 0;
-                state <= 0;
-         end
-
-         if (state == 1 && op == `OP_READ) begin
-                op <= 0;
-                state <= 2;
-                transmit <= 1;
-                tx_byte <= mem_out[7:0];
-         end
-
-         if (state == 2 && transmit) begin
-                transmit <= 0;
-         end
-
-         if (state == 2 && !transmit && !is_transmitting) begin
-                state <= 3;
-                transmit <= 1;
-                tx_byte <= mem_out[15:8];
-         end
-
-         if (state == 3) begin
-                transmit <= 0;
-                state <= 0;
-         end
-   end
+   assign led = worker_led | master_led;
 endmodule
diff --git a/worker.v b/worker.v
new file mode 100644 (file)
index 0000000..7a5a909
--- /dev/null
+++ b/worker.v
@@ -0,0 +1,160 @@
+`include "pll.v"
+`include "ram.v"
+`include "chip.v"
+`include "uart.v"
+
+`ifdef SIM
+ `define UART_DIVIDE 1
+`else
+ `define UART_DIVIDE 1
+ // s/192/3/ for 19200 baud uart
+`endif
+
+module worker (input CLKin, output [4:0] led, output uart_tx, input uart_rx, output reg ready_out = 1, input ready_in);
+   wire clk;
+   wire clk_tmp;
+
+   //pll pll (.clock_in(CLKin), .clock_out(clk));
+
+   reg [20:0] counter = 0;
+
+   reg                   clk = 0;
+
+   always @ (posedge CLKin) begin
+         if(counter == 5000) begin
+                counter <= 0;
+                clk <= 1 - clk;
+         end
+         else
+               counter <= counter + 1;
+   end
+
+   wire [11:0] mem_addr;
+   wire [63:0] mem_in;
+   wire [63:0] mem_out;
+   wire           mem_write;
+
+   RAM #(.ADDRESS_BITS(8)) ram (.clk(clk), .write(mem_write), .addr(mem_addr), .in(mem_in), .out(mem_out));
+
+   reg [7:0]   from_uart [3:0];
+   reg [2:0]   uart_ptr = 0;
+
+   wire [15:0] I  = {from_uart[1], from_uart[0]};
+   assign mem_addr = from_uart[2];
+   wire [2:0]  op_from_uart = from_uart[3][2:0];
+   wire           CS = from_uart[3][3];
+
+   reg [2:0]   op = 0;
+
+   reg [2:0]   last_op = 0;
+
+   reg [15:0]  I;
+   reg                    CS;
+
+   chip chip (.clk(clk), .op(op), .I(I), .io_pin(0), .CS(CS), .mem_in(mem_in), .mem_out(mem_out), .mem_write(mem_write));
+
+   wire           received;
+   wire [7:0]  rx_byte;
+   reg                    transmit = 0;
+   reg  [7:0]  tx_byte = 0;
+   wire           is_receiving;
+   wire           is_transmitting;
+
+   // 19200 (actually 300) baud uart
+   uart #(.CLOCK_DIVIDE(`UART_DIVIDE)) uart (.clk(clk), .rx(uart_rx), .tx(uart_tx), .received(received), .transmit(transmit), .tx_byte(tx_byte), .rx_byte(rx_byte), .is_receiving(is_receiving), .is_transmitting(is_transmitting));
+
+   assign led[0] = is_transmitting;
+   assign led[4] = received;
+//   assign led[3:1] = last_op;
+
+   assign led[2] = |mem_out; // so that mem_out is used
+
+   // 0 is idle
+`define STATE_IDLE 0
+`define STATE_PROPAGATE 1
+`define STATE_EXECUTE 2
+`define STATE_ROUTE 3
+
+   reg [5:0]   state = 0;
+
+//   assign led[4:2] = state;
+
+   always @ (posedge clk) begin
+         case(state)
+               `STATE_IDLE: begin
+                  if(uart_ptr == 4) begin
+                         last_op <= op_from_uart;
+                         uart_ptr <= 0;
+                         state <= `STATE_PROPAGATE;
+                         ready_out <= 0;
+                  end
+                  else if (received) begin
+                         from_uart[uart_ptr] <= rx_byte;
+                         uart_ptr <= uart_ptr + 1;
+                  end else
+                        ready_out <= 1;
+               end
+
+               `STATE_PROPAGATE: begin
+                  if(transmit)
+                         transmit <= 0;
+                  else if(uart_ptr == 4) begin
+                         uart_ptr <= 0;
+                         if(op == `OP_ROUTE) begin
+                                state <= `STATE_ROUTE;
+                         end else begin
+                                op <= last_op;
+                                state <= `STATE_EXECUTE;
+                         end
+                  end else if(!is_transmitting && ready_in) begin
+                         tx_byte <= from_uart[uart_ptr];
+                         transmit <= 1;
+                         uart_ptr <= uart_ptr + 1;
+                  end
+               end
+
+               `STATE_EXECUTE: begin
+                  op <= 0;
+                  state <= `STATE_IDLE;
+               end
+
+               `STATE_ROUTE: begin
+                  state <= `STATE_IDLE; // for now
+               end
+         endcase
+
+         /*
+
+         if (state == 1 && op != `OP_READ) begin
+                op <= 0;
+                state <= 0;
+         end
+
+         if (state == 1 && op == `OP_READ) begin
+                op <= 0;
+                state <= 2;
+                transmit <= 1;
+                tx_byte <= mem_out[7:0];
+         end
+
+         if (state == 2 && transmit) begin
+                transmit <= 0;
+         end
+
+         if (state == 2 && !transmit && !is_transmitting) begin
+                state <= 3;
+                transmit <= 1;
+                tx_byte <= mem_out[15:8];
+         end
+
+         if (state == 3) begin
+                transmit <= 0;
+                state <= 0;
+         end */
+   end
+
+   wire ready = (state == 0 && !is_receiving);
+
+   assign ready_out = ready_in & ready;
+
+endmodule
This page took 0.026764 seconds and 4 git commands to generate.