First version, probably does not work
authorMarius Gavrilescu <marius@ieval.ro>
Mon, 22 Oct 2018 14:45:30 +0000 (15:45 +0100)
committerMarius Gavrilescu <marius@ieval.ro>
Mon, 22 Oct 2018 14:45:30 +0000 (15:45 +0100)
Makefile
chip.v [new file with mode: 0644]
ram.v
toplevel.v [new file with mode: 0644]

index df0855a93bc98b0a7a906b34742d26c8e3d39b4b..64606370a5316b756a95158e6f162cf6fe53d260 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,11 @@
-PROJ = lisp_processor
-PIN_DEF = lisp_processor.pcf
+PROJ = toplevel
+PIN_DEF = toplevel.pcf
 DEVICE = hx1k
 
 all: $(PROJ).rpt $(PROJ).bin
 
 %.blif: %.v
-       tools/yosys/yosys -p 'synth_ice40 -top cpu -blif $@' $<
+       tools/yosys/yosys -p 'synth_ice40 -top toplevel -blif $@' $<
 
 %.asc: $(PIN_DEF) %.blif
        tools/arachne-pnr/bin/arachne-pnr -d $(subst hx,,$(subst lp,,$(DEVICE))) -o $@ -p $^ -P tq144
diff --git a/chip.v b/chip.v
new file mode 100644 (file)
index 0000000..610ad6f
--- /dev/null
+++ b/chip.v
@@ -0,0 +1,219 @@
+`define OP_NOP   3'd0
+`define OP_LOADA 3'd1
+`define OP_LOADB 3'd2
+`define OP_STORE 3'd3
+`define OP_READ  3'd4
+`define OP_LOADI 3'd5
+`define OP_ROUTE 3'd6
+`define OP_RUG   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];
+
+   // OP_LOADB
+   wire [2:0] cond = I[2:0];
+   wire          inv = I[3];
+   wire [7:0] alus = I[11:4];
+
+   // OP_STORE
+   wire [2:0] flagw = I[2:0];
+   wire          edge_ = I[7];
+   wire [3:0] cube = I[11:8];
+
+   // OP_ROUTE
+   wire [5:0] cycle = I[5:0];
+   wire [1:0] check = I[7:6];
+   wire [3:0] xor_  = I[11:8];
+   wire [2:0] snarf = I[14:12];
+   wire          odd   = I[15];
+
+   // OP_RUG
+   wire          rw = I[0];
+   wire          ac = I[1];
+   wire          news = I[2];
+   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] 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;
+
+   always @* begin
+         case(op)
+               `OP_LOADA:
+                 flags_addr <= flagr;
+               `OP_LOADB:
+                 flags_addr <= cond;
+               `OP_STORE:
+                 flags_addr <= flagw;
+               default:
+                 flags_addr <= 0;
+         endcase
+   end
+
+   wire [15:0] flags_in;
+   reg  [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]  idx;
+
+   always @ (posedge clk) begin
+         if(mem_write)
+               mem_write <= 0;
+         if(flags_write)
+               flags_write <= 0;
+
+         case (op)
+               `OP_NOP: begin end
+
+               `OP_LOADA:
+                 begin
+                        alu_carry <= aluc;
+                        F <= flags_out;
+                        A <= mem_out;
+                        C <= mem_out;
+                        io <= io_pin;
+                        if (bsel)
+                          B <= cube_in;
+                 end
+
+               `OP_LOADB:
+                 begin
+                        alu_sum <= alus;
+                        Cond <= inv ? ~flags_out : flags_out;
+                        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;
+                        mem_in <= alu_sum_out;
+                        mem_write <= 1;
+                        // lots other stuff
+                 end
+
+               `OP_READ:
+                 begin
+                        if (CS)
+                          mem_in <= mem_out;
+                 end
+
+               `OP_LOADI:
+                 begin
+                        C <= mem_out;
+                        A <= I;
+                        alu_sum <= 8'b11110000; // out of A, B, F, select exactly A
+                 end
+
+/*             `OP_RUG:
+                 begin
+                        if(!rw && ac && !news)
+                          begin
+                                 rug[reg_] <= A;
+                                 C <= mem_out;
+                          end
+                        if(!rw && !ac && !news)
+                          begin
+                                 rug[reg_] <= C;
+                                 A <= mem_out;
+                          end
+                        if(rw && ac && !news)
+                          begin
+                                 A <= rug[reg_];
+                                 mem_in <= C;
+                          end
+                        if(rw && !ac && !news)
+                          begin
+                                 C <= rug[reg_];
+                                 mem_in <= A;
+                          end
+                        if(rw && !ac && news)
+                          begin
+                                 R <= mem_out;
+                                 cube_in <= mem_out;
+                          end
+                        if(rw && ac && news)
+                          begin
+                                 cube_in <= mem_out;
+                          end
+                 end
+*/
+         endcase
+   end
+endmodule
diff --git a/ram.v b/ram.v
index a7e69fdba3fef648cea21853597b4df7face8bdd..372067543aa9f8de99ede34f79bd53d4962872ac 100644 (file)
--- a/ram.v
+++ b/ram.v
@@ -1,22 +1,11 @@
-// RAM module with single input addr, input and output ports, a write enable and clock input.
-// Data is clocked out of, and into, the RAM on positive clock edges.
+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);
 
-module RAM #(parameter DATA_BITS = 8,  parameter ADDRESS_BITS = 4)
+    reg [15:0] memory [0:2**ADDRESS_BITS-1];
 
-(input clk, input write, input[ADDRESS_BITS-1:0] addr, input[DATA_BITS-1:0] in_data, output[DATA_BITS-1:0] out_data);
-   
-   reg [DATA_BITS-1:0] memorySpace [0:2**ADDRESS_BITS-1];                          
-
-   reg [DATA_BITS-1:0] data_out_reg;
-   
-   always @ (posedge clk) begin
-
-       if (write) memorySpace[addr] <= in_data;
-
-       data_out_reg <= memorySpace[addr];
-       
+    always @ (negedge clk) begin
+        if (write)
+                 memory[addr] <= in;
+        out <= memory[addr];
     end
-
-   assign out_data = data_out_reg;
-   
 endmodule
diff --git a/toplevel.v b/toplevel.v
new file mode 100644 (file)
index 0000000..728fee4
--- /dev/null
@@ -0,0 +1,70 @@
+`include "ram.v"
+`include "chip.v"
+`include "uart.v"
+
+module toplevel (input CLKin, output [4:0] led, output uart_tx, input uart_rx);
+   wire clk = CLKin;
+
+   wire [11:0] mem_addr;
+   wire [15:0] mem_in;
+   wire [15:0] mem_out;
+   wire           mem_write;
+
+   RAM #(.ADDRESS_BITS(12)) 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;
+
+   assign led = uart_ptr;
+
+   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;
+
+   uart uart (.clk(clk), .rx(uart_rx), .tx(uart_tx), .received(received), .transmit(transmit), .tx_byte(tx_byte), .rx_byte(rx_byte));
+
+   reg [15:0]  rom_I [0:5];
+   reg [7:0]  rom_mem_addr [0:5];
+   reg [2:0]  rom_op [0:5];
+   reg                   rom_CS [0:5];
+
+   reg [2:0]   state = 0;
+
+   always @ (posedge clk) begin
+         if (received) begin
+                from_uart[uart_ptr] <= rx_byte;
+                uart_ptr <= uart_ptr + 1;
+         end
+
+         if (uart_ptr == 4) begin
+                op <= op_from_uart;
+                uart_ptr <= 0;
+                state <= 1;
+         end
+
+         if (state == 1) begin
+                transmit <= 1;
+                tx_byte <= mem_in;
+                state <= 2;
+         end
+
+         if (state == 2) begin
+                transmit <= 0;
+                state <= 0;
+         end
+
+         if (op != 0) begin
+                op <= 0;
+         end
+   end
+endmodule
This page took 0.016446 seconds and 4 git commands to generate.