diff --git a/fpga/gpmc/xilinx/common/logic_analyzer_data_storage.v b/fpga/gpmc/xilinx/common/logic_analyzer_data_storage.v new file mode 100644 index 0000000..c5cae3c --- /dev/null +++ b/fpga/gpmc/xilinx/common/logic_analyzer_data_storage.v @@ -0,0 +1,44 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// +// (c) 2014 Timothy Pearson, Raptor Engineering +// Released into the Public Domain +// +////////////////////////////////////////////////////////////////////////////////// + +module logic_analyzer_data_storage( + input clka, + input clkb, + input [63:0] dina, + input [63:0] dinb, + input [8:0] addra, + input [8:0] addrb, + input wea, + input web, + output reg [63:0] douta, + output reg [63:0] doutb); + + parameter RAM_WIDTH = 64; + + // Xilinx specific directive + (* RAM_STYLE="BLOCK" *) + + reg [RAM_WIDTH-1:0] data_storage_ram [(2**9)-1:0]; + + always @(posedge clka) begin + douta <= data_storage_ram[addra]; + if (wea) begin + data_storage_ram[addra] <= dina; + douta <= dina; + end + end + + always @(posedge clkb) begin + doutb <= data_storage_ram[addrb]; + if (web) begin + data_storage_ram[addrb] <= dinb; + doutb <= dinb; + end + end + +endmodule diff --git a/fpga/gpmc/xilinx/common/main.v b/fpga/gpmc/xilinx/common/main.v index a06565a..6d8c743 100644 --- a/fpga/gpmc/xilinx/common/main.v +++ b/fpga/gpmc/xilinx/common/main.v @@ -114,6 +114,26 @@ module main( .wea(lcd_data_storage_wea), .web(lcd_data_storage_web), .douta(lcd_data_storage_douta), .doutb(lcd_data_storage_doutb)); + wire logic_analyzer_data_storage_clka; + wire logic_analyzer_data_storage_clkb; + reg [63:0] logic_analyzer_data_storage_dina; + reg [63:0] logic_analyzer_data_storage_dinb; + reg [8:0] logic_analyzer_data_storage_addra; + reg [8:0] logic_analyzer_data_storage_addrb; + reg logic_analyzer_data_storage_wea; + reg logic_analyzer_data_storage_web; + wire [63:0] logic_analyzer_data_storage_douta; + wire [63:0] logic_analyzer_data_storage_doutb; + + assign logic_analyzer_data_storage_clka = clk; + assign logic_analyzer_data_storage_clkb = clk; + + logic_analyzer_data_storage logic_analyzer_data_storage(.clka(logic_analyzer_data_storage_clka), .clkb(logic_analyzer_data_storage_clkb), + .dina(logic_analyzer_data_storage_dina), .dinb(logic_analyzer_data_storage_dinb), + .addra(logic_analyzer_data_storage_addra), .addrb(logic_analyzer_data_storage_addrb), + .wea(logic_analyzer_data_storage_wea), .web(logic_analyzer_data_storage_web), + .douta(logic_analyzer_data_storage_douta), .doutb(logic_analyzer_data_storage_doutb)); + //----------------------------------------------------------------------------------- // // Create a 12.5MHz clock for the seven-segement LED emulator @@ -215,6 +235,47 @@ module main( end end + //----------------------------------------------------------------------------------- + // + // Logic analyzer + // + //----------------------------------------------------------------------------------- + + reg logic_analyzer_trigger; + reg logic_analyzer_trigger_prev; + reg [9:0] logic_analyzer_address_counter; + always @(posedge clk) begin + // Trigger + logic_analyzer_trigger = ~userlogic_reset; // Trigger on userlogic_reset falling edge + if ((logic_analyzer_trigger == 1) && (logic_analyzer_trigger_prev == 0)) begin + logic_analyzer_address_counter = 0; + end + + // Data load + if (logic_analyzer_address_counter < 9'b100000000) begin + logic_analyzer_data_storage_addrb = logic_analyzer_address_counter; + + // Connect signals to logic analyzer + logic_analyzer_data_storage_dinb[3:0] = four_bit_leds; + logic_analyzer_data_storage_dinb[7:4] = four_bit_switches; + logic_analyzer_data_storage_dinb[15:8] = eight_bit_leds; + logic_analyzer_data_storage_dinb[23:16] = eight_bit_switches; + logic_analyzer_data_storage_dinb[27:24] = sseg_mux; + logic_analyzer_data_storage_dinb[35:28] = sseg_data; + logic_analyzer_data_storage_dinb[43:36] = usermem_data; + logic_analyzer_data_storage_dinb[59:44] = usermem_address; + logic_analyzer_data_storage_dinb[60] = usermem_wen; + logic_analyzer_data_storage_dinb[61] = usermem_wait; + logic_analyzer_data_storage_dinb[62] = 1'b0; + logic_analyzer_data_storage_dinb[63] = 1'b0; + + logic_analyzer_data_storage_web = 1'b1; + logic_analyzer_address_counter = logic_analyzer_address_counter + 1; + end + + logic_analyzer_trigger_prev = logic_analyzer_trigger; + end + //----------------------------------------------------------------------------------- // @@ -247,10 +308,12 @@ module main( gpmc_address_reg = gpmc_address; data_storage_write_enable = 1'b0; lcd_data_storage_wea = 1'b0; + logic_analyzer_data_storage_wea = 1'b0; end if (gpmc_wen_reg == 1'b1) begin data_storage_write_enable = 1'b0; lcd_data_storage_wea = 1'b0; + logic_analyzer_data_storage_wea = 1'b0; end if (gpmc_address_reg[RAM_ADDR_BITS] == 1'b1) begin @@ -320,8 +383,9 @@ module main( // 0x0c: User device control // Bit 0: User logic reset // 0x20 - 0x3f: LCD data area + // 0x1000 - 0x1fff: Logic analyzer data area (read only) if (gpmc_wen_reg == 1'b0) begin - if (gpmc_address_reg[(RAM_ADDR_BITS-1):5] == 1) begin // Address range 0x20 - 0x3f + if (gpmc_address_reg[(RAM_ADDR_BITS-1):5] == 1) begin // Address range 0x20 - 0x3f lcd_data_storage_addra = gpmc_address_reg[4:0]; lcd_data_storage_dina = gpmc_data_reg; lcd_data_storage_wea = 1'b1; @@ -351,10 +415,39 @@ module main( endcase end end else begin - if (gpmc_address_reg[(RAM_ADDR_BITS-1):5] == 1) begin // Address range 0x20 - 0x3f + if (gpmc_address_reg[(RAM_ADDR_BITS-1):5] == 1) begin // Address range 0x20 - 0x3f lcd_data_storage_addra = gpmc_address_reg[4:0]; lcd_data_storage_wea = 1'b0; gpmc_data_out = lcd_data_storage_douta; + end else if (gpmc_address_reg[(RAM_ADDR_BITS-1):12] == 1) begin // Address range 0x1000 - 0x1fff + logic_analyzer_data_storage_addra = gpmc_address_reg[12:3]; + logic_analyzer_data_storage_wea = 1'b0; + case (gpmc_address_reg[2:0]) + 0: begin + gpmc_data_out = logic_analyzer_data_storage_douta[7:0]; + end + 1: begin + gpmc_data_out = logic_analyzer_data_storage_douta[15:8]; + end + 2: begin + gpmc_data_out = logic_analyzer_data_storage_douta[23:16]; + end + 3: begin + gpmc_data_out = logic_analyzer_data_storage_douta[31:24]; + end + 4: begin + gpmc_data_out = logic_analyzer_data_storage_douta[39:32]; + end + 5: begin + gpmc_data_out = logic_analyzer_data_storage_douta[47:40]; + end + 6: begin + gpmc_data_out = logic_analyzer_data_storage_douta[55:48]; + end + 7: begin + gpmc_data_out = logic_analyzer_data_storage_douta[63:56]; + end + endcase end else begin case (gpmc_address_reg[(RAM_ADDR_BITS-1):0]) 0: begin diff --git a/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/logic_analyzer_data_storage.v b/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/logic_analyzer_data_storage.v new file mode 120000 index 0000000..1e8f72d --- /dev/null +++ b/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/logic_analyzer_data_storage.v @@ -0,0 +1 @@ +../../../common/logic_analyzer_data_storage.v \ No newline at end of file diff --git a/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/ulab_debug_interface.xise b/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/ulab_debug_interface.xise index 565fe9a..ac7f1e3 100644 --- a/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/ulab_debug_interface.xise +++ b/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/ulab_debug_interface.xise @@ -17,18 +17,22 @@ - + - + - + + + + + @@ -93,6 +97,7 @@ + @@ -326,7 +331,7 @@ - +