system_cpu16_vga40x30.v (4273B)
1 // Copyright 2015, Brian Swetland <swetland@frotz.net> 2 // Licensed under the Apache License, Version 2.0. 3 4 `default_nettype none 5 6 `timescale 1ns / 1ps 7 8 `define WITH_CPU 9 10 module system_cpu16_vga40x30 #( 11 parameter BPP = 2 12 )( 13 input clk12m_in, 14 output [BPP-1:0]vga_red, 15 output [BPP-1:0]vga_grn, 16 output [BPP-1:0]vga_blu, 17 output vga_hsync, 18 output vga_vsync, 19 output vga_active, 20 output vga_clk, 21 input spi_mosi, 22 output spi_miso, 23 input spi_clk, 24 input spi_cs, 25 input uart_rx, 26 output uart_tx, 27 output led_red, 28 output led_grn, 29 output out1, 30 output out2 31 ); 32 33 wire clk12m; 34 wire clk25m; 35 36 assign out1 = clk12m; 37 assign out2 = clk25m; 38 39 pll_12_25 pll0( 40 .clk12m_in(clk12m_in), 41 .clk12m_out(clk12m), 42 .clk25m_out(clk25m), 43 .lock(), 44 .reset(1'b1) 45 ); 46 47 wire sys_clk; 48 49 `ifdef USE_HFOSC 50 SB_HFOSC #( 51 .CLKHF_DIV("0b00") 52 )hfosc( 53 .CLKHFEN(1'b1), 54 .CLKHFPU(1'b1), 55 .CLKHF(sys_clk) 56 ); 57 `else 58 assign sys_clk = clk12m; 59 `endif 60 61 reg cpu_reset = 1'b0; 62 63 // cpu memory interface 64 wire [15:0]ins_rd_addr; 65 wire [15:0]ins_rd_data; 66 wire ins_rd_req; 67 68 wire [15:0]dat_rw_addr; 69 wire [15:0]dat_rd_data; 70 wire dat_rd_req; 71 wire [15:0]dat_wr_data; 72 wire dat_wr_req; 73 74 `ifndef WITH_CPU 75 assign ins_rd_req = 1'b0; 76 assign dat_rd_req = 1'b0; 77 assign dat_wr_req = 1'b0; 78 assign ins_rd_addr = 16'd0; 79 assign dat_rw_addr = 16'd0; 80 `else 81 // fake arbitration that never denies a request 82 reg ins_rd_rdy = 1'b0; 83 reg dat_rd_rdy = 1'b0; 84 reg dat_wr_rdy = 1'b0; 85 86 always_ff @(posedge sys_clk) begin 87 if (cpu_reset) begin 88 ins_rd_rdy <= 1'b0; 89 dat_rd_rdy <= 1'b0; 90 dat_wr_rdy <= 1'b0; 91 end else begin 92 ins_rd_rdy <= ins_rd_req; 93 dat_rd_rdy <= dat_rd_req; 94 dat_wr_rdy <= dat_wr_req; 95 end 96 end 97 98 // until arbitration works 99 assign dat_rd_data = 16'hEEEE; 100 101 cpu16 cpu( 102 .clk(sys_clk), 103 .ins_rd_addr(ins_rd_addr), 104 .ins_rd_data(ins_rd_data), 105 .ins_rd_req(ins_rd_req), 106 .ins_rd_rdy(ins_rd_rdy), 107 108 .dat_rw_addr(dat_rw_addr), 109 .dat_wr_data(dat_wr_data), 110 .dat_rd_data(dat_rd_data), 111 .dat_rd_req(dat_rd_req), 112 .dat_rd_rdy(dat_rd_rdy), 113 .dat_wr_req(dat_wr_req), 114 .dat_wr_rdy(dat_wr_rdy), 115 116 .reset(cpu_reset) 117 ) /* synthesis syn_keep=1 */; 118 `endif 119 120 wire [15:0]dbg_waddr; 121 wire [15:0]dbg_wdata; 122 wire dbg_we; 123 124 `ifdef WITH_SPI_DEBUG 125 spi_debug_ifc sdi( 126 .spi_clk(spi_clk), 127 .spi_cs_i(spi_cs), 128 .spi_data_i(spi_mosi), 129 .spi_data_o(spi_miso), 130 .sys_clk(sys_clk), 131 .sys_wr_o(dbg_we), 132 .sys_waddr_o(dbg_waddr), 133 .sys_wdata_o(dbg_wdata) 134 ); 135 `else 136 uart_debug_ifc uart( 137 .sys_clk(sys_clk), 138 .sys_wr(dbg_we), 139 .sys_waddr(dbg_waddr), 140 .sys_wdata(dbg_wdata), 141 .uart_rx(uart_rx), 142 .uart_tx(uart_tx), 143 .led_red(led_red), 144 .led_grn(led_grn) 145 ); 146 `endif 147 148 // debug interface has priority over cpu writes 149 wire we = dbg_we | dat_wr_req; 150 wire [15:0]waddr = dbg_we ? dbg_waddr : dat_rw_addr; 151 wire [15:0]wdata = dbg_we ? dbg_wdata : dat_wr_data; 152 153 wire w_cs_sram = (waddr[15:12] == 4'h0); 154 wire w_cs_vram = (waddr[15:12] == 4'h8); 155 wire w_cs_ctrl = (waddr[15:12] == 4'hF); 156 157 always @(posedge sys_clk) begin 158 if (w_cs_ctrl & we) begin 159 cpu_reset <= wdata[0]; 160 end 161 end 162 163 sram ram0( 164 .clk(sys_clk), 165 .raddr(ins_rd_addr), 166 .rdata(ins_rd_data), 167 .re(ins_rd_req), 168 .waddr(waddr), 169 .wdata(wdata), 170 .we(we & w_cs_sram) 171 ); 172 173 wire [BPP-1:0]vr; 174 wire [BPP-1:0]vg; 175 wire [BPP-1:0]vb; 176 177 vga40x30x2 #( 178 .BPP(BPP), 179 .RGB(0) 180 ) vga ( 181 .clk25m(clk25m), 182 .red(vr), 183 .grn(vg), 184 .blu(vb), 185 .hs(vga_hsync), 186 .vs(vga_vsync), 187 .fr(), 188 .active(vga_active), 189 .vram_waddr(waddr[10:0]), 190 .vram_wdata(wdata[15:0]), 191 .vram_we(we & w_cs_vram), 192 .vram_clk(sys_clk) 193 ); 194 195 assign vga_clk = clk25m; 196 197 // hack: flip display from blue to red when CPU is held in reset 198 assign vga_red = cpu_reset ? vb : vr; 199 assign vga_grn = vg; 200 assign vga_blu = cpu_reset ? vr : vb; 201 202 endmodule 203 204 module sram( 205 input clk, 206 input [15:0]raddr, 207 output [15:0]rdata, 208 input re, 209 input [15:0]waddr, 210 input [15:0]wdata, 211 input we 212 ); 213 214 `ifndef USE_LATTICE_SB_RAM40 215 reg [15:0]mem[255:0]; 216 reg [15:0]ra; 217 always @(posedge clk) begin 218 if (we) 219 mem[waddr[7:0]] <= wdata; 220 if (re) 221 ra <= mem[raddr[7:0]]; 222 end 223 assign rdata = ra; 224 `else 225 226 `ifdef YOSYS 227 SB_RAM40_4K #( 228 .READ_MODE(0), 229 .WRITE_MODE(0) 230 ) 231 `else 232 SB_RAM256x16 233 `endif 234 sram_inst( 235 .RDATA(rdata), 236 .RADDR(raddr[7:0]), 237 .RCLK(clk), 238 .RCLKE(1'b1), 239 .RE(re), 240 .WADDR(waddr[7:0]), 241 .WDATA(wdata), 242 .WCLK(clk), 243 .WCLKE(1'b1), 244 .WE(we), 245 .MASK(16'b0) 246 ); 247 `endif 248 249 endmodule