// // File: jtag2mem_6111.v // Date: 09-Dec-05 // Author: I. Chuang // // Verilog module to interface MIT 6.111 labkit to the PC and allow // memory on the FPGA to be loaded to and read from by the PC. // // Uses jtag2mem module. // //--------------------------------------------------------------------------- // // This example creates a small memory and interfaces this to a video // display and also to the JTAG interface (to the PC). The contents of the // memory are displayed in a grid of 24x48 point fonts in a 640x480 // VGA display, with each 8 bit byte mapped to an ASCII character value. // Memory location 3FF is special: it is mapped to the switches. // Memory location 000 is also special; its contents are displayed on the LEDs. // // For debugging, these button actions can be tested: // // button0: displays a counter on the hex displays // button1: displays all "A" characters in text screen // button2: displays the memory value last read as all the characters // button3: displays the vga textgrid coordinates on the hex displays // button_up: red color bars on VGA // button_down: fill memory with value equal to lower 8 bits of address // // To interface to the jtag2mem module on the PC, start a command shell // (start...run and type in "cmd") then at the command line prompt // change your working directory to the one with these files, then // run "xtclsh jtag2mem.tcl" with the approprate arguments. // // For example: // // xtclsh jtag2mem.tcl read 3ff 1 // // reads one byte of the memory at address 3ff (should give switch values) // // xtclsh jtag2mem.tcl write 000 // // lets you write to memory starting at location 000 (should set LEDs) // // Note that to run jtag2mem.tcl, you will need various Xilinx libraries, // including versions of libTclJtag10.dll and libJtagcomm10.dll appropriate // for the release of ISE which you are running. // //--------------------------------------------------------------------------- `include "debounce.v" `include "cmem.v" // 1024*768/12/24 = 672 bytes (8bit wide) `include "jtag2mem.v" `include "display_16hex.v" `include "vga_text.v" module jtag2mem_6111 ( beep, audio_reset_b, ac97_sdata_out, ac97_sdata_in, ac97_synch, ac97_bit_clock, vga_out_red, vga_out_green, vga_out_blue, vga_out_sync_b, vga_out_blank_b, vga_out_pixel_clock, vga_out_hsync, vga_out_vsync, tv_out_ycrcb, tv_out_reset_b, tv_out_clock, tv_out_i2c_clock, tv_out_i2c_data, tv_out_pal_ntsc, tv_out_hsync_b, tv_out_vsync_b, tv_out_blank_b, tv_out_subcar_reset, tv_in_ycrcb, tv_in_data_valid, tv_in_line_clock1, tv_in_line_clock2, tv_in_aef, tv_in_hff, tv_in_aff, tv_in_i2c_clock, tv_in_i2c_data, tv_in_fifo_read, tv_in_fifo_clock, tv_in_iso, tv_in_reset_b, tv_in_clock, ram0_data, ram0_address, ram0_adv_ld, ram0_clk, ram0_cen_b, ram0_ce_b, ram0_oe_b, ram0_we_b, ram0_bwe_b, ram1_data, ram1_address, ram1_adv_ld, ram1_clk, ram1_cen_b, ram1_ce_b, ram1_oe_b, ram1_we_b, ram1_bwe_b, clock_feedback_out, clock_feedback_in, flash_data, flash_address, flash_ce_b, flash_oe_b, flash_we_b, flash_reset_b, flash_sts, flash_byte_b, rs232_txd, rs232_rxd, rs232_rts, rs232_cts, mouse_clock, mouse_data, keyboard_clock, keyboard_data, clock_27mhz, clock1, clock2, disp_blank, disp_data_out, disp_clock, disp_rs, disp_ce_b, disp_reset_b, disp_data_in, button0, button1, button2, button3, button_enter, button_right, button_left, button_down, button_up, switch, led, user1, user2, user3, user4, daughtercard, systemace_data, systemace_address, systemace_ce_b, systemace_we_b, systemace_oe_b, systemace_irq, systemace_mpbrdy, analyzer1_data, analyzer1_clock, analyzer2_data, analyzer2_clock, analyzer3_data, analyzer3_clock, analyzer4_data, analyzer4_clock); output beep, audio_reset_b, ac97_synch, ac97_sdata_out; input ac97_bit_clock, ac97_sdata_in; output [7:0] vga_out_red, vga_out_green, vga_out_blue; output vga_out_sync_b, vga_out_blank_b, vga_out_pixel_clock, vga_out_hsync, vga_out_vsync; output [9:0] tv_out_ycrcb; output tv_out_reset_b, tv_out_clock, tv_out_i2c_clock, tv_out_i2c_data, tv_out_pal_ntsc, tv_out_hsync_b, tv_out_vsync_b, tv_out_blank_b, tv_out_subcar_reset; input [19:0] tv_in_ycrcb; input tv_in_data_valid, tv_in_line_clock1, tv_in_line_clock2, tv_in_aef, tv_in_hff, tv_in_aff; output tv_in_i2c_clock, tv_in_fifo_read, tv_in_fifo_clock, tv_in_iso, tv_in_reset_b, tv_in_clock; inout tv_in_i2c_data; inout [35:0] ram0_data; output [18:0] ram0_address; output ram0_adv_ld, ram0_clk, ram0_cen_b, ram0_ce_b, ram0_oe_b, ram0_we_b; output [3:0] ram0_bwe_b; inout [35:0] ram1_data; output [18:0] ram1_address; output ram1_adv_ld, ram1_clk, ram1_cen_b, ram1_ce_b, ram1_oe_b, ram1_we_b; output [3:0] ram1_bwe_b; input clock_feedback_in; output clock_feedback_out; inout [15:0] flash_data; output [23:0] flash_address; output flash_ce_b, flash_oe_b, flash_we_b, flash_reset_b, flash_byte_b; input flash_sts; output rs232_txd, rs232_rts; input rs232_rxd, rs232_cts; input mouse_clock, mouse_data, keyboard_clock, keyboard_data; input clock_27mhz, clock1, clock2; output disp_blank, disp_clock, disp_rs, disp_ce_b, disp_reset_b; input disp_data_in; output disp_data_out; input button0, button1, button2, button3, button_enter, button_right, button_left, button_down, button_up; input [7:0] switch; output [7:0] led; inout [31:0] user1, user2, user3, user4; inout [43:0] daughtercard; inout [15:0] systemace_data; output [6:0] systemace_address; output systemace_ce_b, systemace_we_b, systemace_oe_b; input systemace_irq, systemace_mpbrdy; output [15:0] analyzer1_data, analyzer2_data, analyzer3_data, analyzer4_data; output analyzer1_clock, analyzer2_clock, analyzer3_clock, analyzer4_clock; //////////////////////////////////////////////////////////////////////////// // // I/O Assignments // //////////////////////////////////////////////////////////////////////////// // Audio Input and Output assign beep= 1'b0; assign audio_reset_b = 1'b0; assign ac97_synch = 1'b0; assign ac97_sdata_out = 1'b0; // ac97_sdata_in is an input // VGA Output /* assign vga_out_red = 10'h0; assign vga_out_green = 10'h0; assign vga_out_blue = 10'h0; assign vga_out_sync_b = 1'b1; assign vga_out_blank_b = 1'b1; assign vga_out_pixel_clock = 1'b0; assign vga_out_hsync = 1'b0; assign vga_out_vsync = 1'b0; */ // Video Output assign tv_out_ycrcb = 10'h0; assign tv_out_reset_b = 1'b0; assign tv_out_clock = 1'b0; assign tv_out_i2c_clock = 1'b0; assign tv_out_i2c_data = 1'b0; assign tv_out_pal_ntsc = 1'b0; assign tv_out_hsync_b = 1'b1; assign tv_out_vsync_b = 1'b1; assign tv_out_blank_b = 1'b1; assign tv_out_subcar_reset = 1'b0; // Video Input assign tv_in_i2c_clock = 1'b0; assign tv_in_fifo_read = 1'b0; assign tv_in_fifo_clock = 1'b0; assign tv_in_iso = 1'b0; assign tv_in_reset_b = 1'b0; assign tv_in_clock = 1'b0; assign tv_in_i2c_data = 1'bZ; // tv_in_ycrcb, tv_in_data_valid, tv_in_line_clock1, tv_in_line_clock2, // tv_in_aef, tv_in_hff, and tv_in_aff are inputs // SRAMs assign ram0_data = 36'hZ; assign ram0_address = 19'h0; assign ram0_adv_ld = 1'b0; assign ram0_clk = 1'b0; assign ram0_cen_b = 1'b1; assign ram0_ce_b = 1'b1; assign ram0_oe_b = 1'b1; assign ram0_we_b = 1'b1; assign ram0_bwe_b = 4'hF; assign ram1_data = 36'hZ; assign ram1_address = 19'h0; assign ram1_adv_ld = 1'b0; assign ram1_clk = 1'b0; assign ram1_cen_b = 1'b1; assign ram1_ce_b = 1'b1; assign ram1_oe_b = 1'b1; assign ram1_we_b = 1'b1; assign ram1_bwe_b = 4'hF; assign clock_feedback_out = 1'b0; // clock_feedback_in is an input // Flash ROM assign flash_data = 16'hZ; assign flash_address = 24'h0; assign flash_ce_b = 1'b1; assign flash_oe_b = 1'b1; assign flash_we_b = 1'b1; assign flash_reset_b = 1'b0; assign flash_byte_b = 1'b1; // flash_sts is an input // RS-232 Interface assign rs232_txd = 1'b1; assign rs232_rts = 1'b1; // rs232_rxd and rs232_cts are inputs // PS/2 Ports // mouse_clock, mouse_data, keyboard_clock, and keyboard_data are inputs // LED Displays /* assign disp_blank = 1'b1; assign disp_clock = 1'b0; assign disp_rs = 1'b0; assign disp_ce_b = 1'b1; assign disp_reset_b = 1'b0; assign disp_data_out = 1'b0; */ // disp_data_in is an input // Buttons, Switches, and Individual LEDs // assign led = 8'hFF; // button0, button1, button2, button3, button_enter, button_right, // button_left, button_down, button_up, and switches are inputs // User I/Os assign user1 = 32'hZ; assign user2 = 32'hZ; assign user3 = 32'hZ; assign user4 = 32'hZ; // Daughtercard Connectors assign daughtercard = 44'hZ; // SystemACE Microprocessor Port assign systemace_data = 16'hZ; assign systemace_address = 7'h0; assign systemace_ce_b = 1'b1; assign systemace_we_b = 1'b1; assign systemace_oe_b = 1'b1; // systemace_irq and systemace_mpbrdy are inputs // Logic Analyzer assign analyzer1_data = 16'h0; assign analyzer1_clock = 1'b1; assign analyzer2_data = 16'h0; assign analyzer2_clock = 1'b1; assign analyzer3_data = 16'h0; assign analyzer3_clock = 1'b1; assign analyzer4_data = 16'h0; assign analyzer4_clock = 1'b1; //////////////////////////////////////////////////////////// // setup basics // use FPGA's digital clock manager to produce a 50 Mhz clock from 27 Mhz // actual frequency: 49.85 MHz wire clock_50mhz_unbuf,clock_50MHz; DCM vclk1(.CLKIN(clock_27mhz),.CLKFX(clock_50mhz_unbuf)); // synthesis attribute CLKFX_DIVIDE of vclk1 is 13 // synthesis attribute CLKFX_MULTIPLY of vclk1 is 24 // synthesis attribute CLK_FEEDBACK of vclk1 is NONE // synthesis attribute CLKIN_PERIOD of vclk1 is 37 BUFG vclk2(.O(clock_50MHz),.I(clock_50mhz_unbuf)); wire clk = clock_50MHz; // power-on reset generation wire power_on_reset; // remain high for first 16 clocks SRL16 reset_sr (.D(1'b0), .CLK(clk), .Q(power_on_reset), .A0(1'b1), .A1(1'b1), .A2(1'b1), .A3(1'b1)); defparam reset_sr.INIT = 16'hFFFF; // ENTER button is user reset wire reset,user_reset; debounce db1(power_on_reset, clk, ~button_enter, user_reset); assign reset = user_reset | power_on_reset; //////////////////////////////////////////////////////////// // create a small memory for testing wire [9:0] ram_addr; wire [7:0] read_data, write_data; wire ram_we; wire [9:0] v_addr; wire [7:0] v_data; cmem cmem1( ram_addr, v_addr, clk, clk, write_data, read_data, v_data, ram_we ); //////////////////////////////////////////////////////////// // debug: when button_down pressed, fill up memory with increasing sequence reg [63:0] count; always @(posedge clk) count <= count + 1; wire [9:0] ram_addr1, ram_addr2; wire [7:0] write_data1, write_data2; wire ram_we1, ram_we2; wire testfill = ~button_down; assign ram_we = testfill ? ram_we2 : ram_we1; assign ram_addr = testfill ? ram_addr2 : ram_addr1; assign write_data = testfill ? write_data2 : write_data1; assign ram_we2 = count[0]; assign write_data2 = count[8:1]; assign ram_addr2 = count[8:1]; //////////////////////////////////////////////////////////// // video display wire [2:0] rgb; wire pix_clk; wire blank; wire cclk; wire [5:0] cx, cy; reg [7:0] char; vga_text vt1(reset, clk, rgb, vga_out_hsync, vga_out_vsync, pix_clk, blank, cclk, cx, cy, char); assign vga_out_red = ~button_up ? {cx,2'b0} : {8{rgb[0]}}; assign vga_out_green = {8{rgb[1]}}; assign vga_out_blue = {8{rgb[2]}}; assign vga_out_blank_b = ~blank; assign vga_out_pixel_clock = pix_clk; // vga pixel clock assign vga_out_sync_b = 1'b1; assign v_addr = cx + cy*26; always @(posedge clk) char <= ~button1 ? "A" : ~button2 ? read_data : cclk ? v_data : char; //////////////////////////////////////////////////////////// // memory-mapped LED's (jtag write) reg [7:0] led_reg; always @(posedge clk) led_reg <= (ram_addr1==0) ? write_data1 : led_reg; //////////////////////////////////////////////////////////// // memory-mapped switches (jtag read) wire [7:0] read_data1 = (ram_addr1=={10{1'b1}}) ? switch : read_data; //////////////////////////////////////////////////////////// // JTAG interface // // read_data1, ram_addr1, ram_we1 connect to the memory, through // some multiplers used for debugging and demos. wire [3:0] state; jtag2mem #(.DBITS(8),.ABITS(10)) j2m(reset, clk, read_data1, write_data1, ram_addr1, ram_we1, state); //////////////////////////////////////////////////////////// // debug assign led = ~led_reg; reg [63:0] hexdata; always @(posedge clk) hexdata <= ~button0 ? count : ~button3 ? {2'b0,v_addr,8'b0,2'b0,cx, 2'b0,cy, 28'b0, v_data} : {2'b0,ram_addr,4'b0,8'b0,8'b0,read_data,8'b0, write_data, 4'b0, state}; display_16hex hexdisp1(reset, clk, hexdata, disp_blank, disp_clock, disp_rs, disp_ce_b, disp_reset_b, disp_data_out); endmodule