uart_debug_ifc.sv (2834B)
1 // Copyright 2018, Brian Swetland <swetland@frotz.net> 2 // Licensed under the Apache License, Version 2.0. 3 4 `default_nettype none 5 6 module uart_debug_ifc( 7 input sys_clk, 8 output sys_wr, 9 output [15:0]sys_waddr, 10 output [15:0]sys_wdata, 11 input uart_rx, 12 output uart_tx, 13 output led_red, 14 output led_grn 15 ); 16 17 reg crc_rst = 1'b0; 18 reg crc_rst_next; 19 20 wire crc_din; 21 wire crc_en; 22 wire [7:0]crc; 23 24 wire [7:0]rxdata; 25 wire rxready; 26 27 uart_rx rx_uart( 28 .clk(sys_clk), 29 .rx(uart_rx), 30 .data(rxdata), 31 .ready(rxready), 32 .crc_din(crc_din), 33 .crc_en(crc_en) 34 ); 35 36 crc8_serial rx_crc( 37 .clk(sys_clk), 38 .din(crc_din), 39 .en(crc_en), 40 .rst(crc_rst), 41 .crc(crc) 42 ); 43 44 reg wr = 1'b0; 45 reg wr_next; 46 47 reg [31:0]addr = 32'd0; 48 reg [31:0]data = 32'd0; 49 reg [7:0]cmd = 8'd0; 50 51 reg [7:0]cmd_next; 52 reg [7:0]dat0_next; 53 reg [7:0]dat1_next; 54 reg [7:0]dat2_next; 55 reg [7:0]dat3_next; 56 reg [31:0]addr_next; 57 58 localparam SINIT = 3'd0; 59 localparam SCMD = 3'd1; 60 localparam SDAT0 = 3'd2; 61 localparam SDAT1 = 3'd3; 62 localparam SDAT2 = 3'd4; 63 localparam SDAT3 = 3'd5; 64 localparam SCRC = 3'd6; 65 localparam SIDLE = 3'd7; 66 67 reg [2:0]state = SINIT; 68 reg [2:0]state_next; 69 70 reg error = 1'b0; 71 reg error_next; 72 73 always_comb begin 74 state_next = state; 75 wr_next = 1'b0; 76 crc_rst_next = 1'b0; 77 cmd_next = cmd; 78 dat0_next = data[7:0]; 79 dat1_next = data[15:8]; 80 dat2_next = data[23:16]; 81 dat3_next = data[31:24]; 82 addr_next = addr; 83 error_next = error; 84 85 case (state) 86 SINIT: begin 87 state_next = SIDLE; 88 crc_rst_next = 1'b1; 89 end 90 SIDLE: begin 91 if (rxready) begin 92 if (rxdata == 8'hCD) begin 93 state_next = SCMD; 94 end else begin 95 error_next = 1'b1; 96 crc_rst_next = 1'b1; 97 end 98 end 99 end 100 SCMD: begin 101 if (rxready) begin 102 state_next = SDAT0; 103 cmd_next = rxdata; 104 end 105 end 106 SDAT0: begin 107 if (rxready) begin 108 state_next = SDAT1; 109 dat0_next = rxdata; 110 end 111 end 112 SDAT1: begin 113 if (rxready) begin 114 state_next = SDAT2; 115 dat1_next = rxdata; 116 end 117 end 118 SDAT2: begin 119 if (rxready) begin 120 state_next = SDAT3; 121 dat2_next = rxdata; 122 end 123 end 124 SDAT3: begin 125 if (rxready) begin 126 state_next = SCRC; 127 dat3_next = rxdata; 128 end 129 end 130 SCRC: begin 131 if (rxready) begin 132 state_next = SIDLE; 133 crc_rst_next = 1'b1; 134 if (crc == 8'd0) begin 135 case (cmd) 136 8'h00: wr_next = 1'b1; 137 8'h01: addr_next = data; 138 8'h02: error_next = 1'b0; 139 default: error_next = 1'b1; 140 endcase 141 end else begin 142 error_next = 1'b1; 143 end 144 end 145 end 146 endcase 147 end 148 149 always_ff @(posedge sys_clk) begin 150 state <= state_next; 151 cmd <= cmd_next; 152 addr <= wr ? (addr + 32'd1) : addr_next; 153 data <= { dat3_next, dat2_next, dat1_next, dat0_next }; 154 crc_rst <= crc_rst_next; 155 wr <= wr_next; 156 error <= error_next; 157 end 158 159 assign sys_wr = wr; 160 assign sys_waddr = addr[15:0]; 161 assign sys_wdata = data[15:0]; 162 163 assign led_grn = ~(crc == 8'd0); 164 assign led_red = ~error; 165 166 assign uart_tx = uart_rx; 167 168 endmodule