gateware

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 398d5a6472fcd41c5ff2823bdb0bc6a84348bae4
parent bdc9a5090407e29bbfab9ca0ec808158438073d3
Author: Brian Swetland <swetland@frotz.net>
Date:   Sun,  9 Dec 2018 08:43:45 -0800

cleanup: make things tidier

- parameterize vga* around BPP
- separate board-level "top"s into board_xyz.v board_xyz.pcf
- system_xyz.v is a system package wrapped/parameterized by boards
- rename some generic ice40* stuff for clarity
- remove unused pcf

Diffstat:
Ahdl/board_icebreaker_vga444.pcf | 25+++++++++++++++++++++++++
Ahdl/board_icebreaker_vga444.v | 32++++++++++++++++++++++++++++++++
Ahdl/board_lattice_evb.pcf | 19+++++++++++++++++++
Ahdl/board_lattice_evb.v | 36++++++++++++++++++++++++++++++++++++
Dhdl/ice40.pcf | 18------------------
Dhdl/ice40.v | 218-------------------------------------------------------------------------------
Dhdl/ice40up.pcf | 19-------------------
Ahdl/system_cpu16_vga40x30.v | 224+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mhdl/vga/chardata.v | 13+++++++++----
Mhdl/vga/vga.v | 20+++++++++++---------
Mhdl/vga/vga40x30x2.v | 36+++++++++++++++++-------------------
Aproject/cpu16-icebreaker-vga444.def | 10++++++++++
Mproject/cpu16-lattice-evb.def | 4++--
13 files changed, 385 insertions(+), 289 deletions(-)

diff --git a/hdl/board_icebreaker_vga444.pcf b/hdl/board_icebreaker_vga444.pcf @@ -0,0 +1,25 @@ +set_io clk12m_in 35 + +set_io vga_red[0] 4 +set_io vga_red[1] 2 +set_io vga_red[2] 47 +set_io vga_red[3] 45 +set_io vga_blu[0] 3 +set_io vga_blu[1] 48 +set_io vga_blu[2] 46 +set_io vga_blu[3] 44 +set_io vga_grn[0] 43 +set_io vga_grn[1] 38 +set_io vga_grn[2] 34 +set_io vga_grn[3] 31 +set_io vga_hsync 42 +set_io vga_vsync 36 + +set_io spi_miso 14 +set_io spi_mosi 17 +set_io spi_clk 15 +set_io spi_cs 16 + +set_io out1 32 +set_io out2 28 +set_io uart_tx 37 diff --git a/hdl/board_icebreaker_vga444.v b/hdl/board_icebreaker_vga444.v @@ -0,0 +1,32 @@ +// Copyright 2018, Brian Swetland <swetland@frotz.net> +// Licensed under the Apache License, Version 2.0. + +module top( + input clk12m_in, + output [3:0]vga_red, + output [3:0]vga_grn, + output [3:0]vga_blu, + output vga_hsync, + output vga_vsync, + output out1, + output out2 + ); + +system_cpu16_vga40x30 #( + .BPP(4) + ) system ( + .clk12m_in(clk12m_in), + .vga_red(vga_red), + .vga_grn(vga_grn), + .vga_blu(vga_blu), + .vga_hsync(vga_hsync), + .vga_vsync(vga_vsync), + .spi_mosi(), + .spi_miso(), + .spi_clk(), + .spi_cs(), + .out1(out1), + .out2(out2) + ); + +endmodule diff --git a/hdl/board_lattice_evb.pcf b/hdl/board_lattice_evb.pcf @@ -0,0 +1,19 @@ +set_io clk12m_in 35 + +set_io vga_red[0] 23 +set_io vga_grn[0] 25 +set_io vga_red[1] 26 +set_io vga_grn[1] 27 +set_io vga_blu[1] 32 +set_io vga_blu[0] 31 +set_io vga_hsync 34 +set_io vga_vsync 43 + +set_io spi_miso 14 +set_io spi_mosi 17 +set_io spi_clk 15 +set_io spi_cs 16 + +set_io out1 3 +set_io out2 4 +set_io uart_tx 28 diff --git a/hdl/board_lattice_evb.v b/hdl/board_lattice_evb.v @@ -0,0 +1,36 @@ +// Copyright 2018, Brian Swetland <swetland@frotz.net> +// Licensed under the Apache License, Version 2.0. + +module top( + input clk12m_in, + output [1:0]vga_red, + output [1:0]vga_grn, + output [1:0]vga_blu, + output vga_hsync, + output vga_vsync, + input spi_mosi, + output spi_miso, + input spi_clk, + input spi_cs, + output out1, + output out2 + ); + +system_cpu16_vga40x30 #( + .BPP(2) + ) system ( + .clk12m_in(clk12m_in), + .vga_red(vga_red), + .vga_grn(vga_grn), + .vga_blu(vga_blu), + .vga_hsync(vga_hsync), + .vga_vsync(vga_vsync), + .spi_mosi(spi_mosi), + .spi_miso(spi_miso), + .spi_clk(spi_clk), + .spi_cs(spi_cs), + .out1(out1), + .out2(out2) + ); + +endmodule diff --git a/hdl/ice40.pcf b/hdl/ice40.pcf @@ -1,18 +0,0 @@ -set_io clk12m C2 -io_std SB_LVCMOS -pullup no - -set_io vga_b[0] D6 -io_std SB_LVCMOS -pullup no -set_io vga_b[1] D5 -io_std SB_LVCMOS -pullup no -set_io vga_g[0] E3 -io_std SB_LVCMOS -pullup no -set_io vga_g[1] F3 -io_std SB_LVCMOS -pullup no -set_io vga_hsync E5 -io_std SB_LVCMOS -pullup no -set_io vga_r[0] F6 -io_std SB_LVCMOS -pullup no -set_io vga_r[1] F5 -io_std SB_LVCMOS -pullup no -set_io vga_vsync E6 -io_std SB_LVCMOS -pullup no - -set_io spi_miso F2 -io_std SB_LVCMOS -pullup no -set_io spi_mosi D1 -io_std SB_LVCMOS -pullup no -set_io spi_clk E1 -io_std SB_LVCMOS -pullup no -set_io spi_cs F1 -io_std SB_LVCMOS -pullup no - -set_io out1 B1 -io_std SB_LVCMOS -pullup no -set_io out2 B2 -io_std SB_LVCMOS -pullup no diff --git a/hdl/ice40.v b/hdl/ice40.v @@ -1,218 +0,0 @@ -// 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; - -`ifdef USE_HFOSC -SB_HFOSC #( - .CLKHF_DIV("0b00") - )hfosc( - .CLKHFEN(1'b1), - .CLKHFPU(1'b1), - .CLKHF(sys_clk) - ); -`else -assign sys_clk = clk12m; -`endif - -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 w_cs_sram = (waddr[15:12] == 4'h0); -wire w_cs_vram = (waddr[15:12] == 4'h8); -wire w_cs_ctrl = (waddr[15:12] == 4'hF); - -always @(posedge sys_clk) begin - if (w_cs_ctrl & we) begin - cpu_reset <= wdata[0]; - end -end - -sram ram0( - .clk(sys_clk), - .raddr(ins_rd_addr), - .rdata(ins_rd_data), - .re(ins_rd_req), - .waddr(waddr), - .wdata(wdata), - .we(we & w_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 & w_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 USE_LATTICE_SB_RAM40 -reg [15:0]mem[255:0]; -reg [15:0]ra; -always @(posedge clk) begin - if (we) - mem[waddr[7:0]] <= wdata; - if (re) - ra <= mem[raddr[7:0]]; -end -assign rdata = ra; -`else - -`ifdef YOSYS -SB_RAM40_4K #( - .READ_MODE(0), - .WRITE_MODE(0) - ) -`else -SB_RAM256x16 -`endif - 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(16'b0) - ); -`endif - -endmodule diff --git a/hdl/ice40up.pcf b/hdl/ice40up.pcf @@ -1,19 +0,0 @@ -set_io clk12m_in 35 - -set_io vga_r[0] 23 -set_io vga_g[0] 25 -set_io vga_r[1] 26 -set_io vga_g[1] 27 -set_io vga_b[1] 32 -set_io vga_b[0] 31 -set_io vga_hsync 34 -set_io vga_vsync 43 - -set_io spi_miso 14 -set_io spi_mosi 17 -set_io spi_clk 15 -set_io spi_cs 16 - -set_io out1 3 -set_io out2 4 -set_io uart_tx 28 diff --git a/hdl/system_cpu16_vga40x30.v b/hdl/system_cpu16_vga40x30.v @@ -0,0 +1,224 @@ +// Copyright 2015, Brian Swetland <swetland@frotz.net> +// Licensed under the Apache License, Version 2.0. + +`timescale 1ns / 1ps + +`define WITH_CPU + +module system_cpu16_vga40x30 #( + parameter BPP = 2 +)( + input clk12m_in, + output [BPP-1:0]vga_red, + output [BPP-1:0]vga_grn, + output [BPP-1:0]vga_blu, + 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; + +`ifdef USE_HFOSC +SB_HFOSC #( + .CLKHF_DIV("0b00") + )hfosc( + .CLKHFEN(1'b1), + .CLKHFPU(1'b1), + .CLKHF(sys_clk) + ); +`else +assign sys_clk = clk12m; +`endif + +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 w_cs_sram = (waddr[15:12] == 4'h0); +wire w_cs_vram = (waddr[15:12] == 4'h8); +wire w_cs_ctrl = (waddr[15:12] == 4'hF); + +always @(posedge sys_clk) begin + if (w_cs_ctrl & we) begin + cpu_reset <= wdata[0]; + end +end + +sram ram0( + .clk(sys_clk), + .raddr(ins_rd_addr), + .rdata(ins_rd_data), + .re(ins_rd_req), + .waddr(waddr), + .wdata(wdata), + .we(we & w_cs_sram) + ); + +wire [BPP-1:0]vr; +wire [BPP-1:0]vg; +wire [BPP-1:0]vb; + +vga40x30x2 #( + .BPP(BPP) + ) 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 & w_cs_vram), + .vram_clk(sys_clk) + ); + +// hack: flip display from blue to red when CPU is held in reset +assign vga_red = cpu_reset ? vb : vr; +assign vga_grn = vg; +assign vga_blu = 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 USE_LATTICE_SB_RAM40 +reg [15:0]mem[255:0]; +reg [15:0]ra; +always @(posedge clk) begin + if (we) + mem[waddr[7:0]] <= wdata; + if (re) + ra <= mem[raddr[7:0]]; +end +assign rdata = ra; +`else + +`ifdef YOSYS +SB_RAM40_4K #( + .READ_MODE(0), + .WRITE_MODE(0) + ) +`else +SB_RAM256x16 +`endif + 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(16'b0) + ); +`endif + +endmodule diff --git a/hdl/vga/chardata.v b/hdl/vga/chardata.v @@ -11,15 +11,20 @@ `timescale 1ns/1ns -module pixeldata( +module pixeldata #( + parameter BPP = 2 +)( input clk, input newline, input advance, input [7:0] line, - output [11:0] pixel, + output [(3*BPP)-1:0] pixel, input [7:0] vram_data, output [10:0] vram_addr - ); +); + +wire [(3*BPP)-1:0]FG = { 3*BPP { 1'b1 }}; +wire [(3*BPP)-1:0]BG = { { 2*BPP { 1'b0 }}, { BPP { 1'b1 }} }; reg [7:0] pattern_rom [0:1023]; @@ -59,7 +64,7 @@ always_ff @(posedge clk) // the high bit of the pattern shift register is used to // select the FG or BG color and feed out to the vga core -assign pixel = pattern[15] ? 12'hFFF : 12'h00F; +assign pixel = pattern[15] ? FG : BG; always_comb begin next_xpos = xpos; diff --git a/hdl/vga/vga.v b/hdl/vga/vga.v @@ -8,20 +8,22 @@ // // CLK: 25MHz, px=40nS, line=32uS, frame=16.768mS -module vga( +module vga #( + parameter BPP = 4 +)( input clk, output hs, output vs, output fr, - output [3:0] r, - output [3:0] g, - output [3:0] b, + output [BPP-1:0] r, + output [BPP-1:0] g, + output [BPP-1:0] b, output newline, output advance, output [7:0] line, - input [11:0] pixel - ); + input [(3*BPP)-1:0] pixel +); reg hsync = 1'b0; reg vsync = 1'b0; @@ -48,9 +50,9 @@ assign line = adjusted_vcount[8:1]; assign advance = active; assign newline = startline; -assign r = active ? pixel[11:8] : 4'd0; -assign g = active ? pixel[7:4] : 4'd0; -assign b = active ? pixel[3:0] : 4'd0; +assign r = active ? pixel[(3*BPP)-1:(2*BPP)] : { BPP { 1'b0 }}; +assign g = active ? pixel[(2*BPP)-1:BPP] : { BPP { 1'b0 }}; +assign b = active ? pixel[BPP-1:0] : { BPP { 1'b0 }}; always_comb begin next_hsync = hsync; diff --git a/hdl/vga/vga40x30x2.v b/hdl/vga/vga40x30x2.v @@ -1,11 +1,13 @@ // Copyright 2012, Brian Swetland <swetland@frotz.net> // Licensed under the Apache License, Version 2.0. -module vga40x30x2( +module vga40x30x2 #( + parameter BPP = 2 +)( input clk25m, - output [1:0]red, - output [1:0]grn, - output [1:0]blu, + output [BPP-1:0]red, + output [BPP-1:0]grn, + output [BPP-1:0]blu, output hs, output vs, output fr, @@ -13,39 +15,35 @@ module vga40x30x2( input [10:0]vram_waddr, input [7:0]vram_wdata, input vram_we - ); - -wire [3:0]r; -wire [3:0]g; -wire [3:0]b; +); wire newline; wire advance; wire [7:0]line; -wire[11:0]pixel; +wire [(3*BPP)-1:0]pixel; -vga vga0( +vga #( + .BPP(BPP) + ) vga0 ( .clk(clk25m), .hs(hs), .vs(vs), .fr(fr), - .r(r), - .g(g), - .b(b), + .r(red), + .g(grn), + .b(blu), .newline(newline), .advance(advance), .line(line), .pixel(pixel) ); -assign red = r[3:2]; -assign grn = g[3:2]; -assign blu = b[3:2]; - wire [10:0]vram_raddr; wire [7:0]vram_rdata; -pixeldata pixeldata0( +pixeldata #( + .BPP(BPP) + ) pixeldata0 ( .clk(clk25m), .newline(newline), .advance(advance), diff --git a/project/cpu16-icebreaker-vga444.def b/project/cpu16-icebreaker-vga444.def @@ -0,0 +1,10 @@ + +PROJECT_TYPE := nextpnr-ice40 + +PROJECT_SRCS := hdl/board_icebreaker_vga444.v hdl/board_icebreaker_vga444.pcf +PROJECT_SRCS += hdl/system_cpu16_vga40x30.v hdl/lattice/pll_12_25.v +PROJECT_SRCS += hdl/spi_debug_ifc.v +PROJECT_SRCS += hdl/vga/vga40x30x2.v hdl/vga/vga.v hdl/vga/videoram.v hdl/vga/chardata.v +PROJECT_SRCS += hdl/cpu16.sv hdl/cpu16_regs.sv hdl/cpu16_alu.sv + +PROJECT_NEXTPNR_OPTS := --package sg48 --up5k diff --git a/project/cpu16-lattice-evb.def b/project/cpu16-lattice-evb.def @@ -1,10 +1,10 @@ PROJECT_TYPE := nextpnr-ice40 -PROJECT_SRCS := hdl/ice40.v hdl/lattice/pll_12_25.v +PROJECT_SRCS := hdl/board_lattice_evb.v hdl/board_lattice_evb.pcf +PROJECT_SRCS += hdl/system_cpu16_vga40x30.v hdl/lattice/pll_12_25.v PROJECT_SRCS += hdl/spi_debug_ifc.v PROJECT_SRCS += hdl/vga/vga40x30x2.v hdl/vga/vga.v hdl/vga/videoram.v hdl/vga/chardata.v PROJECT_SRCS += hdl/cpu16.sv hdl/cpu16_regs.sv hdl/cpu16_alu.sv -PROJECT_SRCS += hdl/ice40up.pcf PROJECT_NEXTPNR_OPTS := --package sg48 --up5k