From 5a2a82dc19c5d46c250c101202a43ee8375c2e28 Mon Sep 17 00:00:00 2001 From: Marius Gavrilescu Date: Mon, 22 Oct 2018 15:45:30 +0100 Subject: [PATCH] First version, probably does not work --- Makefile | 6 +- chip.v | 219 +++++++++++++++++++++++++++++++++++++++++++++++++++++ ram.v | 25 ++---- toplevel.v | 70 +++++++++++++++++ 4 files changed, 299 insertions(+), 21 deletions(-) create mode 100644 chip.v create mode 100644 toplevel.v diff --git a/Makefile b/Makefile index df0855a..6460637 100644 --- 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 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 a7e69fd..3720675 100644 --- 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 index 0000000..728fee4 --- /dev/null +++ b/toplevel.v @@ -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 -- 2.30.2