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