Digital oscilloscope 4 - more features
Now that the oscilloscope skeleton is working, it is easy to add more functionality.
We need one bit of information to decide which direction we want to trigger on. Let's use bit-0 of the data sent by the PC.
That was easy.
The simplest approach is to use the "async_receiver" gap detection feature. The PC sends control bytes in bursts, and when it stops sending, the FPGA detects it and asserts an "RxD_gap" signal.
We've also added a 4-bit register (HDiv[3:0]) to control the horizontal acquisition rate. When we want to decrease the acquisition rate, either we discard samples coming from the ADC, or we filter/downsample them at the frequency we are interested in.
Edge-slope trigger
Let's add the ability to trigger on a rising-edge or falling-edge. Any oscilloscope can do that.We need one bit of information to decide which direction we want to trigger on. Let's use bit-0 of the data sent by the PC.
| assign Trigger = (RxD_data[0] ^ Threshold1) & (RxD_data[0] ^ ~Threshold2); |
That was easy.
More options
Let's add the ability to control the trigger threshold. That's an 8-bit value. Then we require horizontal acquisition rate control, filtering control... That requires multiple control bytes from the PC to control the oscilloscope.The simplest approach is to use the "async_receiver" gap detection feature. The PC sends control bytes in bursts, and when it stops sending, the FPGA detects it and asserts an "RxD_gap" signal.
|
wire RxD_gap; async_receiver async_rxd(.clk(clk), .RxD(RxD), .RxD_data_ready(RxD_data_ready), .RxD_data(RxD_data), .RxD_gap(RxD_gap)); reg [1:0] RxD_addr_reg; always @(posedge clk) if(RxD_gap) RxD_addr_reg <= 0; else if(RxD_data_ready) RxD_addr_reg <= RxD_addr_reg + 1; // register 0: TriggerThreshold reg [7:0] TriggerThreshold; always @(posedge clk) if(RxD_data_ready & (RxD_addr_reg==0)) TriggerThreshold <= RxD_data; // register 1: "0 0 0 0 HDiv[3] HDiv[2] HDiv[1] HDiv[0]" reg [3:0] HDiv; always @(posedge clk) if(RxD_data_ready & (RxD_addr_reg==1)) HDiv <= RxD_data[3:0]; // register 2: "StartAcq TriggerPolarity 0 0 0 0 0 0" reg TriggerPolarity; always @(posedge clk) if(RxD_data_ready & (RxD_addr_reg==2)) TriggerPolarity <= RxD_data[6]; wire StartAcq = RxD_data_ready & (RxD_addr_reg==2) & RxD_data[7]; |
We've also added a 4-bit register (HDiv[3:0]) to control the horizontal acquisition rate. When we want to decrease the acquisition rate, either we discard samples coming from the ADC, or we filter/downsample them at the frequency we are interested in.