From 9aaa93570dd4a32baabbfe18f6cefbc888c20c7f Mon Sep 17 00:00:00 2001 From: brad Date: Fri, 16 Apr 2010 13:48:04 +0000 Subject: [PATCH] added bootrom --- rtl/bootrom.v | 72 ++++++++++++++++++++++++++++++++++++++++++++ rtl/display.v | 48 +++++++++++++++++++++++++++++ rtl/pdp8.v | 15 ++++++--- rtl/pdp8_ram.v | 14 ++++++++- rtl/sevensegdecode.v | 35 +++++++++++++++++++++ rtl/top.v | 18 ++++++++--- 6 files changed, 192 insertions(+), 10 deletions(-) create mode 100644 rtl/bootrom.v create mode 100644 rtl/display.v create mode 100644 rtl/sevensegdecode.v diff --git a/rtl/bootrom.v b/rtl/bootrom.v new file mode 100644 index 0000000..daf3497 --- /dev/null +++ b/rtl/bootrom.v @@ -0,0 +1,72 @@ +// +// boot rom occupies one page from 7400 - 7577 +// + +module bootrom(clk, reset, addr, data_out, rd, selected); + + input clk; + input reset; + input [14:0] addr; + output [11:0] data_out; + input rd; + output selected; + + // + reg deactivate; + reg [2:0] delay; + reg [11:0] data; + wire active; + + always @(posedge clk) + if (reset) + delay <= 3'o7; + else + if (deactivate || (delay != 3'o7 && delay != 3'o0)) + delay <= delay - 3'o1; + + assign active = delay != 3'b000; + assign selected = active && (addr >= 12'o7400 && addr <= 12'o7577); + + assign data_out = data; + + always @(*) + begin + deactivate = 0; + +//`define debug_rom +`ifdef debug_rom + $display("rom: active %b delay %o addr %o", active, delay, addr); +`endif + + if (rd) + case (addr) + // copy tss8 bootstrap to ram and jump to it + // (see ../rom/rom.pal) + 12'o7400: data = 12'o7240; + 12'o7401: data = 12'o1223; + 12'o7402: data = 12'o3010; + 12'o7403: data = 12'o1216; + 12'o7404: data = 12'o3410; + 12'o7405: data = 12'o1217; + 12'o7406: data = 12'o3410; + 12'o7407: data = 12'o1220; + 12'o7410: data = 12'o3410; + 12'o7411: data = 12'o1221; + 12'o7412: data = 12'o3410; + 12'o7413: data = 12'o1222; + 12'o7414: data = 12'o3410; + 12'o7415: data = 12'o5623; + 12'o7416: data = 12'o7600; + 12'o7417: data = 12'o6603; + 12'o7420: data = 12'o6622; + 12'o7421: data = 12'o5352; + 12'o7422: data = 12'o5752; + 12'o7423: data = 12'o7750; + endcase // case(addr) + + if (rd && addr == 12'o7415) + deactivate = 1; + + end + +endmodule diff --git a/rtl/display.v b/rtl/display.v new file mode 100644 index 0000000..51125d8 --- /dev/null +++ b/rtl/display.v @@ -0,0 +1,48 @@ +// display.v +// display pc on led'and 4x7 segment digits + +module display(clk, reset, pc, dots, sevenseg, sevenseg_an); + + input clk; + input reset; + input [11:0] pc; + input [3:0] dots; + output [7:0] sevenseg; + output [3:0] sevenseg_an; + + // + wire [2:0] digit; + reg [1:0] anode; + + reg [10:0] divider; + reg aclk; + + assign digit = (anode == 2'b11) ? pc[11:9] : + (anode == 2'b10) ? pc[8:6] : + (anode == 2'b01) ? pc[5:3] : + (anode == 2'b00) ? pc[2:0] : + 3'b0; + + assign sevenseg_an = (anode == 2'b11) ? 4'b0111 : + (anode == 2'b10) ? 4'b1011 : + (anode == 2'b01) ? 4'b1101 : + (anode == 2'b00) ? 4'b1110 : + 4'b1111; + + + assign sevenseg[0] = ~dots[anode]; + + sevensegdecode decode({1'b0, digit}, sevenseg[7:1]); + + always @(posedge clk) + begin + divider <= divider + 11'b1; + if (divider == 0) + aclk = ~aclk; + end + + // digit scan clock + always @(posedge aclk) + anode <= anode + 1'b1; + +endmodule diff --git a/rtl/pdp8.v b/rtl/pdp8.v index b106e5d..ab40dec 100644 --- a/rtl/pdp8.v +++ b/rtl/pdp8.v @@ -195,7 +195,7 @@ // (remember that on interrupt, sf <= {if,df}) // -module pdp8(clk, reset, +module pdp8(clk, reset, initial_pc, pc_out, ac_out, ram_addr, ram_data_out, ram_data_in, ram_rd, ram_wr, io_select, io_data_out, io_data_in, io_data_avail, io_interrupt, io_skip, io_clear_ac, @@ -204,12 +204,15 @@ module pdp8(clk, reset, ext_ram_ma, ext_ram_in, ext_ram_out); input clk, reset; + input [14:0] initial_pc; input [11:0] ram_data_in; output ram_rd; output ram_wr; output [11:0] ram_data_out; output [14:0] ram_addr; - + output [11:0] pc_out; + output [11:0] ac_out; + output [5:0] io_select; input [11:0] io_data_in; output [11:0] io_data_out; @@ -365,6 +368,10 @@ module pdp8(clk, reset, H0 = 4'b1100; + // for display + assign pc_out = pc; + assign ac_out = ac; + // // cpu state state machine // @@ -409,7 +416,7 @@ module pdp8(clk, reset, always @(posedge clk) if (reset) - pc <= 0; + pc <= initial_pc[11:0]; else begin pc <= pc_mux; @@ -547,7 +554,7 @@ module pdp8(clk, reset, interrupt_skip <= 0; interrupt <= 0; UI <= 0; - IF <= 0; + IF <= initial_pc[14:12]; DF <= 0; IB <= 0; SF <= 0; diff --git a/rtl/pdp8_ram.v b/rtl/pdp8_ram.v index d634d92..16d80d4 100644 --- a/rtl/pdp8_ram.v +++ b/rtl/pdp8_ram.v @@ -35,6 +35,18 @@ module pdp8_ram(clk, reset, addr, data_in, data_out, rd, wr, .CE_N(1'b0), .WE_N(~wr)); `else + + // + wire rom_decode; + wire [11:0] rom_data; + + bootrom rom(.clk(clk), + .reset(reset), + .addr(addr), + .data_out(rom_data), + .rd(rd), + .selected(rom_decode)); + // wire sram1_ub, sram1_lb; @@ -51,7 +63,7 @@ module pdp8_ram(clk, reset, addr, data_in, data_out, rd, wr, assign sram1_ub_n = ~sram1_ub; assign sram1_lb_n = ~sram1_lb; - assign data_out = sram1_io[11:0]; + assign data_out = rom_decode ? rom_data : sram1_io[11:0]; assign sram1_io = ~sram_oe_n ? 16'bz : {4'b0, data_in}; // sram2 not used diff --git a/rtl/sevensegdecode.v b/rtl/sevensegdecode.v new file mode 100644 index 0000000..50fd018 --- /dev/null +++ b/rtl/sevensegdecode.v @@ -0,0 +1,35 @@ +// sevensegdecode.v +// seven segment decoder for s3board + +module sevensegdecode(digit, ss_out); + + input [3:0] digit; + output [6:0] ss_out; + + // segments abcdefg + // a + // f b + // g + // e c + // d + + assign ss_out = + (digit == 4'd0) ? 7'b0000001 : + (digit == 4'd1) ? 7'b1001111 : + (digit == 4'd2) ? 7'b0010010 : + (digit == 4'd3) ? 7'b0000110 : + (digit == 4'd4) ? 7'b1001100 : + (digit == 4'd5) ? 7'b0100100 : + (digit == 4'd6) ? 7'b1100000 : + (digit == 4'd7) ? 7'b0001111 : + (digit == 4'd8) ? 7'b0000000 : + (digit == 4'd9) ? 7'b0001100 : + (digit == 4'ha) ? 7'b0001001 : + (digit == 4'hb) ? 7'b1100000 : + (digit == 4'hc) ? 7'b0110001 : + (digit == 4'hd) ? 7'b1000010 : + (digit == 4'he) ? 7'b0010000 : + (digit == 4'hf) ? 7'b0111000 : + 7'b1111111; + +endmodule diff --git a/rtl/top.v b/rtl/top.v index f90f310..fca9250 100644 --- a/rtl/top.v +++ b/rtl/top.v @@ -112,16 +112,22 @@ module top(rs232_txd, rs232_rxd, wire ext_ram_done; wire [11:0] ext_ram_out; + wire [14:0] initial_pc; + wire [11:0] pc; + wire [11:0] ac; + debounce reset_sw(.clk(sysclk), .in(button[3]), .out(reset)); -// display show_pc(.clk(sysclk), .reset(reset), -// .pc(pc), .dots(pc[15:12]), -// .led(oled[3:0]), -// .sevenseg(sevenseg), .sevenseg_an(sevenseg_an)); -// assign led = {rk_state, trapped, waited, halted}; + display show_pc(.clk(sysclk), .reset(reset), + .pc(pc), .dots(ac[3:0]), + .sevenseg(sevenseg), .sevenseg_an(sevenseg_an)); + assign led = ac[11:4]; pdp8 cpu(.clk(clk), .reset(reset), + .initial_pc(initial_pc), + .pc_out(pc), + .ac_out(ac), .ram_addr(ram_addr), .ram_data_in(ram_data_out), .ram_data_out(ram_data_in), @@ -189,5 +195,7 @@ module top(rs232_txd, rs232_rxd, .sram2_io(sram2_io), .sram2_ce_n(sram2_ce_n), .sram2_ub_n(sram2_ub_n), .sram2_lb_n(sram2_lb_n)); + assign initial_pc = 15'o07400; + endmodule