📄 lac.v
字号:
//------------------------------------------------------------------ 2 // Logic Analyzer Component 3 //------------------------------------------------------------------ 4 5 module lac #( 6 parameter uart_freq_hz = 100000000, 7 parameter uart_baud = 115200, 8 parameter adr_width = 11, 9 parameter width = 8 10 ) ( 11 input reset, 12 input uart_clk, 13 input uart_rxd, 14 output uart_cts, 15 output uart_txd, 16 input uart_rts, 17 // actual probe input 18 input probe_clk, 19 input [width-1:0] probe, 20 output reg [7:0] select 21 ); 22 23 parameter cmd_nop = 8'h20; 24 parameter cmd_arm = 8'h01; 25 parameter cmd_disarm = 8'h02; 26 27 //------------------------------------------------------------------ 28 // uart instantiation 29 //------------------------------------------------------------------ 30 assign uart_cts = 1; 31 32 reg tx_wr; 33 wire tx_busy; 34 reg [7:0] tx_data; 35 36 wire [7:0] rx_data; 37 wire rx_avail; 38 reg rx_ack; 39 40 uart #( 41 .freq_hz( uart_freq_hz ), 42 .baud( uart_baud ) 43 ) uart0 ( 44 .reset( reset ), 45 .clk( uart_clk ), 46 // UART 47 .uart_txd( uart_txd ), 48 .uart_rxd( uart_rxd ), 49 // 50 .rx_data( rx_data ), 51 .rx_avail( rx_avail ), 52 .rx_error( rx_error ), 53 .rx_ack( rx_ack ), 54 .tx_data( tx_data ), 55 .tx_wr( tx_wr ), 56 .tx_busy( tx_busy ) 57 ); 58 59 //------------------------------------------------------------------ 60 // handshake signal between clock domains 61 //------------------------------------------------------------------ 62 reg [7:0] trig_mask; 63 reg [7:0] trig_cond; 64 reg [7:0] trig_pre; 65 66 reg [adr_width-1:0] start_adr; // set in probe_clk domain 67 68 reg armed; // set in uart_clk domain 69 reg triggered; // set in probe_clk domain 70 71 //------------------------------------------------------------------ 72 // uart state machine 73 //------------------------------------------------------------------ 74 wire rx_req; 75 assign rx_req = rx_avail & ~rx_ack; 76 77 reg triggered_synced; 78 wire [width-1:0] read_dat; 79 reg [adr_width-1:0] read_adr; 80 wire [adr_width-1:0] read_adr_next; 81 82 assign read_adr_next = read_adr + 1; 83 84 reg [2:0] state; 85 86 parameter s_idle = 0; 87 parameter s_read_select= 1; 88 parameter s_read_mask = 2; 89 parameter s_read_comp = 3; 90 parameter s_read_pre = 4; 91 parameter s_triggered = 5; 92 parameter s_send_byte = 6; 93 94 always @(posedge uart_clk) 95 begin 96 if (reset) begin 97 state <= s_idle; 98 select <= 0; 99 armed <= 0; 100 tx_wr <= 0; 101 end else begin 102 triggered_synced <= triggered; 103 104 rx_ack <= 0; // default until set otherwise 105 tx_wr <= 0; 106 107 case (state) 108 s_idle: begin 109 110 if (rx_req) begin 111 case (rx_data) 112 cmd_arm: begin 113 rx_ack <= 1; 114 state <= s_read_select; 115 end 116 cmd_disarm: begin 117 rx_ack <= 1; 118 armed <= 0; 119 end 120 default: begin 121 rx_ack <= 1; 122 end 123 endcase 124 end 125 126 if (~rx_req && triggered_synced) begin 127 state <= s_triggered; 128 end 129 end 130 s_read_select: begin 131 if (rx_req) begin 132 rx_ack <= 1; 133 select <= rx_data; 134 state <= s_read_mask; 135 end 136 end 137 s_read_mask: begin 138 if (rx_req) begin 139 rx_ack <= 1; 140 trig_mask <= rx_data; 141 state <= s_read_comp; 142 end 143 end 144 s_read_comp: begin 145 if (rx_req) begin 146 rx_ack <= 1; 147 trig_cond <= rx_data; 148 armed <= 1; 149 state <= s_read_pre; 150 end 151 end 152 s_read_pre: begin 153 if (rx_req) begin 154 rx_ack <= 1; 155 trig_pre <= rx_data; 156 armed <= 1; 157 state <= s_idle; 158 end 159 end 160 s_triggered: begin 161 armed <= 0; 162 read_adr <= start_adr; 163 tx_data <= adr_width; 164 tx_wr <= 1; 165 state <= s_send_byte; 166 end 167 s_send_byte: begin 168 tx_wr <= 0; 169 170 if (~tx_busy & ~tx_wr) begin 171 if (read_adr_next == start_adr) 172 state <= s_idle; 173 174 read_adr <= read_adr_next; 175 tx_data <= read_dat; 176 tx_wr <= 1; 177 end 178 end 179 default: 180 state <= s_idle; 181 endcase 182 end 183 end 184 185 //------------------------------------------------------------------ 186 // Sampling clock domain 187 //------------------------------------------------------------------ 188 reg armed_synced; 189 reg armed_synced2; 190 reg sampling; 191 192 reg [adr_width-1:0] write_adr; 193 wire [adr_width-1:0] next_adr; 194 assign next_adr = write_adr + 1; 195 196 wire cond_match; 197 assign cond_match = (probe & trig_mask) == (trig_cond & trig_mask) && armed_synced2; 198 199 always @(posedge probe_clk) 200 begin 201 if (reset) begin 202 armed_synced <= 0; 203 armed_synced2 <= 0; 204 sampling <= 0; 205 triggered <= 0; 206 write_adr <= 0; 207 end else begin 208 armed_synced <= armed; 209 armed_synced2 <= armed_synced; 210 211 if (armed_synced2 || sampling) begin 212 write_adr <= next_adr; 213 end 214 215 if (~triggered && armed_synced2) begin 216 if (cond_match) begin 217 sampling <= 1; 218 triggered <= 1; 219 start_adr <= write_adr; 220 end 221 end 222 223 if (sampling && next_adr == start_adr) begin 224 sampling <= 0; 225 end 226 227 if (~sampling && ~armed_synced2 && triggered) 228 triggered <= 0; 229 end 230 end 231 232 233 //------------------------------------------------------------------ 234 // dual port memory 235 //------------------------------------------------------------------ 236 wire write_en; 237 assign write_en = sampling || cond_match; 238 239 dp_ram #( 240 .adr_width( adr_width ), 241 .dat_width( width ) 242 ) ram0 ( 243 // read port a 244 .clk_a( uart_clk ), 245 .adr_a( read_adr ), 246 .dat_a( read_dat ), 247 // write port b 248 .clk_b( probe_clk ), 249 .adr_b( write_adr ), 250 .dat_b( probe ), 251 .we_b( write_en ) 252 ); 253 254 endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -