URL
https://opencores.org/ocsvn/wbscope/wbscope/trunk
Subversion Repositories wbscope
Compare Revisions
- This comparison shows the changes necessary to convert path
/wbscope
- from Rev 2 to Rev 3
- ↔ Reverse comparison
Rev 2 → Rev 3
/trunk/rtl/wbscopc.v
0,0 → 1,141
/////////////////////////////////////////////////////////////////////////// |
// |
// Filename: wbscopc.v |
// |
// Project: FPGA Library of Routines |
// |
// Purpose: This scope is identical in function to the wishbone scope |
// found in wbscope, save that the output is compressed and that |
// (as a result) it can only handle recording 31 bits at a time. |
// This allows the top bit to indicate an 'address'. |
// |
// Reading/decompressing the output of this scope works in this |
// fashion: clear a memory. Then, once the scope has stopped, |
// read from the port. If it's an address (high bit set), then |
// jump to that address. If it's not, then write into that |
// memory location and increment the memory address after writing. |
// |
// I've provided this version of a compressed scope to OpenCores for |
// discussion purposes. While wbscope.v works and works well by itself, |
// this compressed scope has a fundamental flaw that I have yet to fix: |
// The first values out of the scope take place at an unknown address. |
// |
// Ideally, the first item read out of the scope should be a data value, |
// even if the scope was skipping values to a new address at the time. |
// If it was in the middle of a skip, the next item out of the scope |
// should be the skip length. This, though, violates the rule that there |
// are (1<<LGMEMLEN) items in the memory, and that the trigger took place |
// on the last item of memory ... so that portion of this compressed |
// scope is still to be defined. |
// |
// Like I said, this version is placed here for discussion purposes, |
// not because it runs nor because I have recognized that it has any |
// particular value (yet). |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Tecnology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
///////////////////////////////////////////////////////////////////////////// |
// |
// |
module wbscopc(i_clk, i_ce, i_trigger, i_data, |
i_wb_clk, i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data, |
o_wb_ack, o_wb_stall, o_wb_data, |
o_interrupt); |
parameter LGMEM = 5'd10, BUSW = 32, SYNCHRONOUS=1; |
// The input signals that we wish to record |
input i_clk, i_ce, i_trigger; |
input [(BUSW-2):0] i_data; |
// The WISHBONE bus for reading and configuring this scope |
input i_wb_clk, i_wb_cyc, i_wb_stb, i_wb_we; |
input i_wb_addr; // One address line only |
input [(BUSW-1):0] i_wb_data; |
output wire o_wb_ack, o_wb_stall; |
output wire [(BUSW-1):0] o_wb_data; |
// And, finally, for a final flair --- offer to interrupt the CPU after |
// our trigger has gone off. This line is equivalent to the scope |
// being stopped. It is not maskable here. |
output wire o_interrupt; |
|
|
// Let's first see how far we can get by cheating. We'll use the |
// wbscope program, and suffer a lack of several features |
wire lcl_reset; |
assign lcl_reset = (i_wb_cyc)&&(i_wb_stb)&&(~i_wb_addr)&&(i_wb_we) |
&&(~i_wb_data[31]); |
|
reg [(BUSW-2):0] ck_addr; |
initial ck_addr = 0; |
always @(posedge i_clk) |
if (lcl_reset) |
ck_addr <= 0; |
else |
ck_addr <= ck_addr + 1; |
|
reg imm_adr, lst_adr; |
reg [(BUSW-2):0] lst_dat, lst_val, imm_val; |
initial lst_dat = 0; |
initial lst_adr = 1'b1; |
initial imm_adr = 1'b1; |
always @(posedge i_clk) |
if (lcl_reset) |
begin |
imm_val <= 31'h0; |
imm_adr <= 1'b1; |
lst_val <= 31'h0; |
lst_adr <= 1'b1; |
lst_dat <= 31'b0; |
end else if ((i_ce)&&(i_data != lst_dat)) |
begin |
imm_val <= i_data; |
imm_adr <= 1'b0; |
lst_val <= imm_val; |
lst_adr <= imm_adr; |
lst_dat <= i_data; |
end else begin |
imm_val <= ck_addr; |
imm_adr <= 1'b1; |
lst_val <= imm_val; |
lst_adr <= imm_adr; |
end |
|
reg r_ce; |
reg [(BUSW-1):0] r_data; |
initial r_ce = 1'b0; |
always @(posedge i_clk) |
r_ce <= (~lst_adr)||(~imm_adr); |
always @(posedge i_clk) |
r_data <= ((~lst_adr)||(~imm_adr)) |
? { lst_adr, lst_val } |
: { 1'b0, i_data }; |
|
|
wbscope #(.SYNCHRONOUS(1), |
.LGMEM(LGMEM), |
.BUSW(BUSW)) cheatersscope(i_clk, r_ce, i_trigger, r_data, |
i_wb_clk, i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data, |
o_wb_ack, o_wb_stall, o_wb_data, o_interrupt); |
endmodule |