}
sub flag_zero { 0 }
+sub flag_temp { 7 }
sub flag_news { 8 + $_[0] }
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};
+}
+`include "news.v"
+
`define OP_NOP 3'd0
`define OP_LOADA 3'd1
`define OP_LOADB 3'd2
`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
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;
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)
`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
--- /dev/null
+`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
--- /dev/null
+// 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
--- /dev/null
+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
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) ]
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 '};'
}
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
-`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
--- /dev/null
+`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