aboutsummaryrefslogtreecommitdiffstats
path: root/ice40/regressions/issue0148/hdl/ice40.v
diff options
context:
space:
mode:
Diffstat (limited to 'ice40/regressions/issue0148/hdl/ice40.v')
-rw-r--r--ice40/regressions/issue0148/hdl/ice40.v222
1 files changed, 222 insertions, 0 deletions
diff --git a/ice40/regressions/issue0148/hdl/ice40.v b/ice40/regressions/issue0148/hdl/ice40.v
new file mode 100644
index 0000000..f2499a5
--- /dev/null
+++ b/ice40/regressions/issue0148/hdl/ice40.v
@@ -0,0 +1,222 @@
+// Copyright 2015, Brian Swetland <swetland@frotz.net>
+// Licensed under the Apache License, Version 2.0.
+
+`timescale 1ns / 1ps
+
+`define WITH_CPU
+
+module top(
+ input clk12m_in,
+ output [1:0]vga_r,
+ output [1:0]vga_g,
+ output [1:0]vga_b,
+ output vga_hsync,
+ output vga_vsync,
+ input spi_mosi,
+ output spi_miso,
+ input spi_clk,
+ input spi_cs,
+ output out1,
+ output out2
+ );
+
+wire clk12m;
+wire clk25m;
+
+assign out1 = clk12m;
+assign out2 = clk25m;
+
+pll_12_25 pll0(
+ .clk12m_in(clk12m_in),
+ .clk12m_out(clk12m),
+ .clk25m_out(clk25m),
+ .lock(),
+ .reset(1'b1)
+ );
+
+wire sys_clk = clk12m;
+
+reg cpu_reset = 1'b0;
+
+// cpu memory interface
+wire [15:0]ins_rd_addr;
+wire [15:0]ins_rd_data;
+wire ins_rd_req;
+
+wire [15:0]dat_rw_addr;
+wire [15:0]dat_rd_data;
+wire dat_rd_req;
+wire [15:0]dat_wr_data;
+wire dat_wr_req;
+
+`ifndef WITH_CPU
+assign ins_rd_req = 1'b0;
+assign dat_rd_req = 1'b0;
+assign dat_wr_req = 1'b0;
+assign ins_rd_addr = 16'd0;
+assign dat_rw_addr = 16'd0;
+`else
+// fake arbitration that never denies a request
+reg ins_rd_rdy = 1'b0;
+reg dat_rd_rdy = 1'b0;
+reg dat_wr_rdy = 1'b0;
+
+always_ff @(posedge sys_clk) begin
+ if (cpu_reset) begin
+ ins_rd_rdy <= 1'b0;
+ dat_rd_rdy <= 1'b0;
+ dat_wr_rdy <= 1'b0;
+ end else begin
+ ins_rd_rdy <= ins_rd_req;
+ dat_rd_rdy <= dat_rd_req;
+ dat_wr_rdy <= dat_wr_req;
+ end
+end
+
+// until arbitration works
+assign dat_rd_data = 16'hEEEE;
+
+cpu16 cpu(
+ .clk(sys_clk),
+ .ins_rd_addr(ins_rd_addr),
+ .ins_rd_data(ins_rd_data),
+ .ins_rd_req(ins_rd_req),
+ .ins_rd_rdy(ins_rd_rdy),
+
+ .dat_rw_addr(dat_rw_addr),
+ .dat_wr_data(dat_wr_data),
+ .dat_rd_data(dat_rd_data),
+ .dat_rd_req(dat_rd_req),
+ .dat_rd_rdy(dat_rd_rdy),
+ .dat_wr_req(dat_wr_req),
+ .dat_wr_rdy(dat_wr_rdy),
+
+ .reset(cpu_reset)
+ ) /* synthesis syn_keep=1 */;
+`endif
+
+wire [15:0]dbg_waddr;
+wire [15:0]dbg_wdata;
+wire dbg_we;
+
+spi_debug_ifc sdi(
+ .spi_clk(spi_clk),
+ .spi_cs_i(spi_cs),
+ .spi_data_i(spi_mosi),
+ .spi_data_o(spi_miso),
+ .sys_clk(sys_clk),
+ .sys_wr_o(dbg_we),
+ .sys_waddr_o(dbg_waddr),
+ .sys_wdata_o(dbg_wdata)
+ );
+
+// debug interface has priority over cpu writes
+wire we = dbg_we | dat_wr_req;
+wire [15:0]waddr = dbg_we ? dbg_waddr : dat_rw_addr;
+wire [15:0]wdata = dbg_we ? dbg_wdata : dat_wr_data;
+
+wire cs_sram = (waddr[15:12] == 4'h0);
+wire cs_vram = (waddr[15:12] == 4'h8);
+wire cs_ctrl = (waddr[15:12] == 4'hF);
+
+always @(posedge sys_clk) begin
+ if (cs_ctrl & we) begin
+ cpu_reset <= wdata[0];
+ end
+end
+
+//assign out1 = cpu_reset;
+//assign out2 = cpu_raddr[0];
+//assign out1 = dat_wr_req;
+//assign out2 = dbg_we;
+
+wire cs0r = ~ins_rd_addr[8];
+wire cs1r = ins_rd_addr[8];
+wire cs0w = ~waddr[8];
+wire cs1w = waddr[8];
+
+wire [15:0]rdata0;
+wire [15:0]rdata1;
+
+assign ins_rd_data = cs0r ? rdata0 : rdata1;
+
+sram ram0(
+ .clk(sys_clk),
+ .raddr(ins_rd_addr),
+ .rdata(rdata0),
+ .re(ins_rd_req & cs0r & cs_sram),
+ .waddr(waddr),
+ .wdata(wdata),
+ .we(we & cs0w & cs_sram)
+ );
+
+sram ram1(
+ .clk(sys_clk),
+ .raddr(ins_rd_addr),
+ .rdata(rdata1),
+ .re(ins_rd_req & cs1r & cs_sram),
+ .waddr(waddr),
+ .wdata(wdata),
+ .we(we & cs1w & cs_sram)
+ );
+
+wire [1:0]vr, vg, vb;
+
+vga40x30x2 vga(
+ .clk25m(clk25m),
+ .red(vr),
+ .grn(vg),
+ .blu(vb),
+ .hs(vga_hsync),
+ .vs(vga_vsync),
+ .fr(),
+ .vram_waddr(waddr[10:0]),
+ .vram_wdata(wdata[7:0]),
+ .vram_we(we & cs_vram),
+ .vram_clk(sys_clk)
+ );
+
+// hack: flip display from blue to red when CPU is held in reset
+assign vga_r = cpu_reset ? vb : vr;
+assign vga_g = vg;
+assign vga_b = cpu_reset ? vr : vb;
+
+endmodule
+
+module sram(
+ input clk,
+ input [15:0]raddr,
+ output [15:0]rdata,
+ input re,
+ input [15:0]waddr,
+ input [15:0]wdata,
+ input we
+ );
+
+`ifndef uselatticeprim
+reg [15:0]mem[255:0];
+reg [15:0]ra;
+always @(posedge clk) begin
+ if (we)
+ mem[waddr[7:0]] <= wdata;
+ if (re)
+ ra <= raddr;
+end
+assign rdata = mem[ra[7:0]];
+`else
+SB_RAM256x16 sram_inst(
+ .RDATA(rdata),
+ .RADDR(raddr[7:0]),
+ .RCLK(clk),
+ .RCLKE(1'b1),
+ .RE(re),
+ .WADDR(waddr[7:0]),
+ .WDATA(wdata),
+ .WCLK(clk),
+ .WCLKE(1'b1),
+ .WE(we),
+ .MASK()
+ );
+`endif
+
+endmodule