Dangerous Prototypes

In development => Project logs => Topic started by: Richard Sharpe on March 30, 2011, 10:15:27 pm

Title: CheapScope: A simple logic capture device for Xilinx parts
Post by: Richard Sharpe on March 30, 2011, 10:15:27 pm
Hi,

Attached are the source files for my CheapScope implementation. It was done as my project for an Embedded FPGA class I have taken at UC Santa Cruz extension. It is my first FPGA project so it undoubtedly contains many things than can be done better.

It consists of the basic logic capture piece that is parametrized in terms of the width and depth that it can capture to. It defaults to one block ram on Xilinx Spartan/Virtex-5 parts. Ie, 18-bits wide and 1024 samples. It has a free-running sample capture module plus a simple triggering module.

PicoBlaze (KCPSM-5) and the serial_rx and serial_tx implementation from one of Ken Chapman's demo implementations. It works with 0.9.3 of the OLS at 115200 and the PicoBlaze program will supply zeros if asked for too many samples.

It uses two block rams and something like around 300 slices on a Virtex-5 (almost 2% I think).

My next steps, if I find the time, would be to:

1. Possibly convert it to using Xilinx primitives, although I don't know if I can keep the parametrization.

2. Move the interfacing into Verilog and dispense with KCPSM. This will save one block ram and probably not cost many more slices, but I don't know.

3. Package it better so that it can easily be included in another project

This shows how it used currently (Note that some of this code is probably copyright Ken Chapman or Xilinx and is excerpted to show how it is used):

Code: [Select]
kcpsm3 processor
(      .address(address),
        .instruction(instruction),
        .port_id(port_id),
        .write_strobe(write_strobe),
        .out_port(out_port),
        .read_strobe(read_strobe),
        .in_port(in_port),
        .interrupt(interrupt),
        .interrupt_ack(interrupt_ack),
        .reset(1'b0),
        .clk(clk));

cheapscp program_rom
(      .address(address),
        .instruction(instruction),
        .clk(clk));

// The bits that we are going to capture
//
wire [17:0] capture_wires;

// Change this to specify what to capture ...
// These are the address on KCPSM and part of the instruction, which turned
// out to be useful for debugging
assign capture_wires = {address, instruction[17:10]};

wire sample_capture_start;
wire sample_capture_done;
wire sample_cmd_stb;
wire sample_data_stb;
wire [7:0] sample_in_data;

cheapscope_first sample_inst(
                .sys_clk(clk),
                .rst(1'b0),
                .capture_bits(capture_wires),
                .capture_start(sample_capture_start),
                .capture_done(sample_capture_done),
                .cmd(out_port),
                .cmd_stb(sample_cmd_stb),
                .write_data(out_port),
                .write_stb(sample_data_stb),
                .read_data(sample_in_data)
                );

wire [7:0] capture_status_port;

assign capture_status_port = {6'b000000, sample_capture_start, sample_capture_done};

//--------------------------------------------------------------------------------------------------------------------------------
// KCPSM3 input ports
//--------------------------------------------------------------------------------------------------------------------------------
//
//
// UART FIFO status signals to form a bus
//

  assign uart_status_port = {3'b 000,rx_data_present,rx_full,rx_half_full,tx_full,tx_half_full};

//
// The inputs connect via a pipelined multiplexer
// Port 2 is for the LCD. Port 4 is for capture engine command out and status in
// Port 5 is for capture engine data out and data in
//

  always @(posedge clk) begin
    case(port_id[2:0] )
    // read UART status at address 00 hex
    3'b000 :
        begin
      in_port <= uart_status_port;
        end
    // read UART receive data at address 01 hex
    3'b001 :
        begin
      in_port <= rx_data;
        end
        // The Capture status
        3'b100 :
                begin
                        in_port <= capture_status_port;
                end
        // The read port on the capture engine
        3'b101 :
                begin
                        in_port <= sample_in_data;
                end
    // Don't care used for all other addresses to ensure minimum logic implementation
    default :
        begin
      in_port <= 8'b XXXXXXXX;
        end
    endcase

//--------------------------------------------------------------------------------------------------------------------------------
// KCPSM3 output ports
//--------------------------------------------------------------------------------------------------------------------------------
//
// adding the output registers to the clock processor
  always @(posedge clk) begin
    if(write_strobe == 1'b1) begin
      // Alarm register at address 00 hex with data bit0 providing control -- ignored!
      case (port_id[2:0])
                3'b000: begin
                                //ld_r <= out_port[3:0];
                        end
                3'b010:
                        begin // The LCD is on port 2 ... see below
                                if (lcd_state == LCD_IDLE) begin
                                        lcd_val <= out_port;
                                        lcd_start <= 1'b1;
                                end
                        end
                default:
                        begin
                                lcd_start <= 1'b0;
                        end
      endcase
        end
        if (lcd_state != LCD_IDLE) begin
                lcd_start <= 1'b0;
        end
  end

assign sample_cmd_stb = write_strobe & (port_id[2:0] == 3'b100);
assign sample_data_stb = write_strobe & (port_id[2:0] == 3'b101);


I have not bothered showing the UART rx and tx instances nor the clock generator ... they can be obtained elsewhere.

I will upload a screen shot of the OLS client with a grab of the capture as well as:

1. cheapscope_simple.v, the logic capture engine
2. byte_to_reg.v, something I seemed to need to make some things parametrized
3. cheapscp.psm
Title: Re: CheapScope: A simple logic capture device for Xilinx par
Post by: Richard Sharpe on March 30, 2011, 10:20:57 pm
Hmm, it seems that I cannot attach raw Verilog files so I will have to package them together as a zip file or something.
Title: Re: CheapScope: A simple logic capture device for Xilinx par
Post by: Richard Sharpe on March 31, 2011, 03:19:34 am
Attached are the files I said I would add. They are in a zip file.
Title: Re: CheapScope: A simple logic capture device for Xilinx par
Post by: ian on March 31, 2011, 07:55:15 am
Hi Richard,

Thanks for sharing! Is this an open version of the ChipScope tool in Xilinx?
Title: Re: CheapScope: A simple logic capture device for Xilinx par
Post by: Richard Sharpe on March 31, 2011, 04:35:05 pm
No, it is not.

I am in no way affiliated with Xilinx.

I just took a class that was run by a guy from Xilinx and he suggested this as a project idea and I thought I would give it a go.

It is a very simple subset of the ChipScope functionality, I believe (although I have not used ChipScope).

The name is a joke on Xilinx' ChipScope.

I do hope to improve it over time, though, but as it is my first FPGA project, I am sure that it has many flaws.
Title: Re: CheapScope: A simple logic capture device for Xilinx par
Post by: ian on March 31, 2011, 04:49:55 pm
Hi Richard,

Thanks for the background. That is what I meant too :) A home-brew version with some functionality of the ChipScope. I have never used it personally either, but I'm really interested to check out your project.
Title: Re: CheapScope: A simple logic capture device for Xilinx par
Post by: Richard Sharpe on March 31, 2011, 05:03:33 pm
My first improvement will be to turn it into a stand-alone module. I have discussed the issues of reusing the UART pieces supplied by Ken Chapman with our instructor, and he suggests that there are no such issues.

What I would like to do is implement something like:

  module cheapscope_simple(clk, signals, tx, rx)

so that all you have to do is instantiate just that. At the moment it is a bit of a dogs breakfast. You should then be able to specify parameters like the capture width, capture depth (size of RAMS), clock frequency and UART speed ... currently only capture width and depth are parameters, but I realized last night in getting it to work on the instructor's Spartan-3 board from Digilent that the clock frequency to UART bit-rate generator needed to be changed.

This will probably re-use the rx and tx pieces from Ken Chapman that use Xilinx primitives, but it could also be re-implemented with open versions of the rx and tx modules.

In discussion last night we concluded that ChipScope might use JTAG to communicate with the other tools, but for compatibility with the OLS client, it is better to use serial communications.

( ! ) Fatal error: Uncaught exception 'Elk_Exception' with message 'Please try again. If you come back to this error screen, report the error to an administrator.' in /var/www/dangerousprototypes/forum/sources/database/Db-mysql.class.php on line 696
( ! ) Elk_Exception: Please try again. If you come back to this error screen, report the error to an administrator. in /var/www/dangerousprototypes/forum/sources/database/Db-mysql.class.php on line 696
Call Stack
#TimeMemoryFunctionLocation
10.00932083104session_write_close ( )...(null):0
20.00962214680ElkArte\sources\subs\SessionHandler\DatabaseHandler->write( )...(null):0
30.00962215456Database_MySQL->query( ).../DatabaseHandler.php:119
40.05302354176Database_MySQL->error( ).../Db-mysql.class.php:273