diff --git a/firmware/AtomBusMon.c b/firmware/AtomBusMon.c
index 5c95f70..8523175 100644
--- a/firmware/AtomBusMon.c
+++ b/firmware/AtomBusMon.c
@@ -69,12 +69,35 @@ char *modeStrings[7] = {
"Instruction watch",
"Read watch",
"Write watch",
- "Undefined",
+ "Undefined"
};
-#define VERSION "0.21"
+#define NUM_TRIGGERS 16
+#define TRIGGER_ALWAYS 15
-#define NUMCMDS 18
+char *triggerStrings[NUM_TRIGGERS] = {
+ "Never",
+ "~T0 and ~T1",
+ "T0 and ~T1",
+ "~T1",
+ "~T0 and T1",
+ "~T0",
+ "T0 xor T1",
+ "~T0 or ~T1",
+ "T0 and T1",
+ "T0 xnor T1",
+ "T0",
+ "T0 or ~T1",
+ "T1",
+ "~T0 or T1",
+ "T0 or T1",
+ "Always",
+};
+
+
+#define VERSION "0.22"
+
+#define NUM_CMDS 19
#define MAXBKPTS 8
int numbkpts = 0;
@@ -84,6 +107,10 @@ long trace;
long instructions = 1;
unsigned int breakpoints[MAXBKPTS] = {
+ 0,
+ 0,
+ 0,
+ 0,
0,
0,
0,
@@ -91,6 +118,21 @@ unsigned int breakpoints[MAXBKPTS] = {
};
unsigned int modes[MAXBKPTS] = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+unsigned int triggers[MAXBKPTS] = {
+ 0,
+ 0,
+ 0,
+ 0,
0,
0,
0,
@@ -98,7 +140,7 @@ unsigned int modes[MAXBKPTS] = {
};
-char *cmdStrings[NUMCMDS] = {
+char *cmdStrings[NUM_CMDS] = {
"help",
"reset",
"step",
@@ -116,7 +158,8 @@ char *cmdStrings[NUMCMDS] = {
"wcleari",
"wclearr",
"wclearw",
- "continue",
+ "trigger",
+ "continue"
};
#define Delay_us(__us) \
@@ -247,6 +290,14 @@ void logMode(unsigned int mode) {
}
}
+void logTrigger(unsigned int trigger) {
+ if (trigger >= 0 && trigger < NUM_TRIGGERS) {
+ log0("trigger: %s", triggerStrings[trigger]);
+ } else {
+ log0("trigger: ILLEGAL");
+ }
+}
+
int logDetails() {
unsigned int i_addr = hwRead16(OFFSET_BW_IAL);
unsigned int b_addr = hwRead16(OFFSET_BW_BAL);
@@ -266,6 +317,25 @@ int logDetails() {
return watch;
}
+int lookupBreakpoint(char *params) {
+ int i;
+ int n = 0;
+ sscanf(params, "%x", &n);
+ // First, look assume n is an address, and try to map to an index
+ for (i = 0; i < numbkpts; i++) {
+ if (breakpoints[i] == n) {
+ n = i;
+ break;
+ }
+ }
+ if (n < numbkpts) {
+ return n;
+ }
+ log0("Breakpoint/watch not set at %04X\n", n);
+ return -1;
+}
+
+
/*******************************************
* Commands
*******************************************/
@@ -274,9 +344,13 @@ void doCmdHelp(char *params) {
int i;
version();
log0("Commands:\n");
- for (i = 0; i < NUMCMDS; i++) {
+ for (i = 0; i < NUM_CMDS; i++) {
log0(" %s\n", cmdStrings[i]);
}
+ log0("Trigger Codes:\n");
+ for (i = 0; i < NUM_TRIGGERS; i++) {
+ log0(" %X = %s\n", i, triggerStrings[i]);
+ }
}
void doCmdAddr() {
@@ -287,8 +361,6 @@ void doCmdAddr() {
log0("%04X\n", i_addr);
}
-
-
void doCmdStep(char *params) {
long i;
long j;
@@ -337,31 +409,39 @@ void doCmdBList(char *params) {
for (i = 0; i < numbkpts; i++) {
log0("%d: %04X: ", i, breakpoints[i]);
logMode(modes[i]);
- log0("\n");
+ log0(" (");
+ logTrigger(triggers[i]);
+ log0(")\n");
}
} else {
log0("No breakpoints set\n");
}
}
-void setBreakpoint(int i, int addr, int mode) {
+void setBreakpoint(int i, unsigned int addr, unsigned int mode, unsigned int trigger) {
logMode(mode);
log0(" set at %04X\n", addr);
breakpoints[i] = addr;
modes[i] = mode;
+ triggers[i] = trigger;
}
void doCmdBreak(char *params, unsigned int mode) {
int i;
unsigned int addr;
- sscanf(params, "%x", &addr);
+ unsigned int trigger = -1;
+ sscanf(params, "%x %x", &addr, &trigger);
for (i = 0; i < numbkpts; i++) {
if (breakpoints[i] == addr) {
if (modes[i] & mode) {
logMode(mode);
log0(" already set at %04X\n", addr);
} else {
- setBreakpoint(i, addr, modes[i] | mode);
+ // Preserve the existing trigger, unless it is overridden
+ if (trigger == -1) {
+ trigger = triggers[i];
+ }
+ setBreakpoint(i, addr, modes[i] | mode, trigger);
}
return;
}
@@ -371,13 +451,18 @@ void doCmdBreak(char *params, unsigned int mode) {
return;
}
numbkpts++;
+ // New breakpoint, so if trigger not specified, set to ALWAYS
+ if (trigger == -1) {
+ trigger = TRIGGER_ALWAYS;
+ }
for (i = numbkpts - 2; i >= -1; i--) {
if (i == -1 || breakpoints[i] < addr) {
- setBreakpoint(i + 1, addr, mode);
+ setBreakpoint(i + 1, addr, mode, trigger);
return;
} else {
breakpoints[i + 1] = breakpoints[i];
modes[i + 1] = modes[i];
+ triggers[i + 1] = triggers[i];
}
}
}
@@ -408,35 +493,26 @@ void doCmdWatchW(char *params) {
void doCmdBClear(char *params, unsigned int mode) {
int i;
- int n = 0;
- sscanf(params, "%x", &n);
- // First, look assume n is an address, and try to map to an index
- for (i = 0; i < numbkpts; i++) {
- if (breakpoints[i] == n) {
- n = i;
- break;
- }
+ int n = lookupBreakpoint(params);
+ if (n < 0) {
+ return;
}
- if (n < numbkpts) {
- if (modes[n] & mode) {
- log0("Removing ");
- logMode(mode);
- log0(" at %04X\n", breakpoints[n]);
- modes[n] &= ~mode;
- if (modes[n] == 0) {
- for (i = n; i < numbkpts; i++) {
- breakpoints[i] = breakpoints[i + 1];
- modes[i] = modes[i + 1];
- }
- numbkpts--;
+ if (modes[n] & mode) {
+ log0("Removing ");
+ logMode(mode);
+ log0(" at %04X\n", breakpoints[n]);
+ modes[n] &= ~mode;
+ if (modes[n] == 0) {
+ for (i = n; i < numbkpts; i++) {
+ breakpoints[i] = breakpoints[i + 1];
+ modes[i] = modes[i + 1];
+ triggers[i] = triggers[i + 1];
}
- } else {
- logMode(mode);
- log0(" not set at %04X\n", breakpoints[n]);
+ numbkpts--;
}
} else {
logMode(mode);
- log0(" not set at %04X\n", n);
+ log0(" not set at %04X\n", breakpoints[n]);
}
}
@@ -464,12 +540,32 @@ void doCmdWClearW(char *params) {
doCmdBClear(params, 1 << WATCH_WRITE);
}
-void shiftBreakpointRegister(unsigned int addr, unsigned int mode) {
+void doCmdTrigger(char *params) {
+ unsigned int trigger = -1;
+ int n = lookupBreakpoint(params);
+ if (n < 0) {
+ return;
+ }
+ sscanf(params, "%*x %x", &trigger);
+ if (trigger >= 0 && trigger < NUM_TRIGGERS) {
+ triggers[n] = trigger;
+ } else {
+ log0("Illegal trigger code (see help for trigger codes)\n");
+ }
+}
+
+void shiftBreakpointRegister(unsigned int addr, unsigned int mode, unsigned int trigger) {
int i;
- long reg = mode;
+ // Trigger is 4 bits
+ long reg = trigger;
+ // Mode is 6 bits
+ reg <<= 6;
+ reg |= mode;
+ // Address is 16 bits
reg <<= 16;
reg |= addr;
- for (i = 0; i <= 21; i++) {
+ // Total size is 26 bits
+ for (i = 0; i <= 25; i++) {
hwCmd(CMD_LOAD_REG, reg & 1);
reg >>= 1;
}
@@ -488,10 +584,10 @@ void doCmdContinue(char *params) {
// Load breakpoints into comparators
for (i = 0; i < numbkpts; i++) {
- shiftBreakpointRegister(breakpoints[i], modes[i]);
+ shiftBreakpointRegister(breakpoints[i], modes[i], triggers[i]);
}
for (i = numbkpts; i < MAXBKPTS; i++) {
- shiftBreakpointRegister(0, 0);
+ shiftBreakpointRegister(0, 0, 0);
}
// Enable breakpoints
@@ -544,7 +640,7 @@ void initialize() {
setTrace(1);
}
-void (*cmdFuncs[NUMCMDS])(char *params) = {
+void (*cmdFuncs[NUM_CMDS])(char *params) = {
doCmdHelp,
doCmdReset,
doCmdStep,
@@ -562,6 +658,7 @@ void (*cmdFuncs[NUMCMDS])(char *params) = {
doCmdWClearI,
doCmdWClearR,
doCmdWClearW,
+ doCmdTrigger,
doCmdContinue
};
@@ -569,17 +666,13 @@ void (*cmdFuncs[NUMCMDS])(char *params) = {
void dispatchCmd(char *cmd) {
int i;
char *cmdString;
-
-
int minLen;
int cmdStringLen;
-
int cmdLen = 0;
while (cmd[cmdLen] >= 'a' && cmd[cmdLen] <= 'z') {
cmdLen++;
}
-
- for (i = 0; i < NUMCMDS; i++) {
+ for (i = 0; i < NUM_CMDS; i++) {
cmdString = cmdStrings[i];
cmdStringLen = strlen(cmdString);
minLen = cmdLen < cmdStringLen ? cmdLen : cmdStringLen;
@@ -600,6 +693,3 @@ int main(void) {
}
return 0;
}
-
-
-
diff --git a/ipcore_dir/WatchEvents.xise b/ipcore_dir/WatchEvents.xise
index 4ae932b..d8a1ff4 100644
--- a/ipcore_dir/WatchEvents.xise
+++ b/ipcore_dir/WatchEvents.xise
@@ -17,11 +17,11 @@
-
+
-
+
@@ -29,341 +29,29 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
diff --git a/src/AtomBusMon.vhd b/src/AtomBusMon.vhd
index 2370853..e4088a8 100644
--- a/src/AtomBusMon.vhd
+++ b/src/AtomBusMon.vhd
@@ -25,7 +25,7 @@ use work.OhoPack.all ;
entity AtomBusMon is
generic (
num_comparators : integer := 8;
- reg_width : integer := 22;
+ reg_width : integer := 26;
fifo_width : integer := 36
);
port (
@@ -38,6 +38,9 @@ entity AtomBusMon is
Sync : in std_logic;
Rdy : out std_logic;
nRST : inout std_logic;
+
+ -- External trigger inputs
+ trig : in std_logic_vector(1 downto 0);
-- HD44780 LCD
lcd_rs : out std_logic;
@@ -211,8 +214,8 @@ begin
lcd_db <= lcd_db_out when lcd_rw_int = '0' else (others => 'Z');
lcd_db_in <= lcd_db;
- led3 <= nRST; -- red
- led6 <= not single; -- red
+ led3 <= not trig(0); -- red
+ led6 <= not trig(1); -- red
led8 <= not brkpt_active; -- green
nrst_avr <= nsw2;
@@ -244,6 +247,7 @@ begin
variable bactive : std_logic;
variable wactive : std_logic;
variable status : std_logic_vector(19 downto 0);
+ variable trigval : std_logic;
begin
bactive := '0';
wactive := '0';
@@ -257,7 +261,10 @@ begin
reg_mode_wi := brkpt_reg(i * reg_width + 19);
reg_mode_war := brkpt_reg(i * reg_width + 20);
reg_mode_waw := brkpt_reg(i * reg_width + 21);
- if (Addr = reg_addr) then
+ trigval := brkpt_reg(i * reg_width + 22 + to_integer(unsigned(trig)));
+ if (trigval = '1' and (Addr = reg_addr or
+ (reg_mode_bi = '0' and reg_mode_bar = '0' and reg_mode_baw = '0' and
+ (reg_mode_wi = '0' and reg_mode_war = '0' and reg_mode_waw = '0')))) then
if (Sync = '1') then
if (reg_mode_bi = '1') then
bactive := '1';
diff --git a/src/constraints.ucf b/src/constraints.ucf
index f7528c3..852f667 100644
--- a/src/constraints.ucf
+++ b/src/constraints.ucf
@@ -11,6 +11,8 @@ NET "lcd_db<7>" LOC="P33" | IOSTANDARD = LVCMOS33 ; # 6847 pin 8
NET "avr_RxD" LOC="P32" | IOSTANDARD = LVCMOS33 ; # 6847 pin 9
NET "avr_TxD" LOC="P34" | IOSTANDARD = LVCMOS33 ; # 6847 pin 10
+NET "trig<0>" LOC="P58" | IOSTANDARD = LVCMOS33 ; # 6847 pin 18
+NET "trig<1>" LOC="P60" | IOSTANDARD = LVCMOS33 ; # 6847 pin 19
NET "nRST" LOC="P61" | IOSTANDARD = LVCMOS33 ; # 6847 pin 20
NET "Addr<0>" LOC="P67" | IOSTANDARD = LVCMOS33 ; # 6847 pin 21
NET "Addr<1>" LOC="P68" | IOSTANDARD = LVCMOS33 ; # 6847 pin 22
@@ -59,8 +61,6 @@ NET tcclk LOC=P50 | IOSTANDARD = LVCMOS33 | DRIVE=16 ;
# NET "" LOC="P35" | IOSTANDARD = LVCMOS33 ; # 6847 pin 14
# NET "" LOC="P53" | IOSTANDARD = LVCMOS33 ; # 6847 pin 15
# NET "" LOC="P54" | IOSTANDARD = LVCMOS33 ; # 6847 pin 16
-# NET "" LOC="P58" | IOSTANDARD = LVCMOS33 ; # 6847 pin 18
-# NET "" LOC="P60" | IOSTANDARD = LVCMOS33 ; # 6847 pin 19
# NET "" LOC="P48" | IOSTANDARD = LVCMOS33 ; # connector pin E2