gateware

A collection of little open source FPGA hobby projects
git clone http://frotz.net/git/gateware.git
Log | Files | Refs | README

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