OpenCores
URL https://opencores.org/ocsvn/uart2bus/uart2bus/trunk

Subversion Repositories uart2bus

[/] [uart2bus/] [trunk/] [verilog/] [rtl/] [uart_parser.v] - Diff between revs 2 and 12

Only display areas with differences | Details | Blame | View Log

Rev 2 Rev 12
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
// uart parser module  
// uart parser module  
//
//
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
 
 
module uart_parser
module uart_parser
(
(
        // global signals 
        // global signals 
        clock, reset,
        clock, reset,
        // transmit and receive internal interface signals from uart interface 
        // transmit and receive internal interface signals from uart interface 
        rx_data, new_rx_data,
        rx_data, new_rx_data,
        tx_data, new_tx_data, tx_busy,
        tx_data, new_tx_data, tx_busy,
        // internal bus to register file 
        // internal bus to register file 
        int_address, int_wr_data, int_write,
        int_address, int_wr_data, int_write,
        int_rd_data, int_read
        int_rd_data, int_read,
 
        int_req, int_gnt
);
);
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
// parameters 
// parameters 
parameter               AW = 8;                 // address bus width parameter 
parameter               AW = 8;                 // address bus width parameter 
 
 
// modules inputs and outputs 
// modules inputs and outputs 
input                   clock;                  // global clock input 
input                   clock;                  // global clock input 
input                   reset;                  // global reset input 
input                   reset;                  // global reset input 
output  [7:0]    tx_data;                // data byte to transmit 
output  [7:0]    tx_data;                // data byte to transmit 
output                  new_tx_data;    // asserted to indicate that there is a new data byte for
output                  new_tx_data;    // asserted to indicate that there is a new data byte for
                                                                // transmission 
                                                                // transmission 
input                   tx_busy;                // signs that transmitter is busy 
input                   tx_busy;                // signs that transmitter is busy 
input   [7:0]    rx_data;                // data byte received 
input   [7:0]    rx_data;                // data byte received 
input                   new_rx_data;    // signs that a new byte was received 
input                   new_rx_data;    // signs that a new byte was received 
output  [AW-1:0] int_address;    // address bus to register file 
output  [AW-1:0] int_address;    // address bus to register file 
output  [7:0]    int_wr_data;    // write data to register file 
output  [7:0]    int_wr_data;    // write data to register file 
output                  int_write;              // write control to register file 
output                  int_write;              // write control to register file 
output                  int_read;               // read control to register file 
output                  int_read;               // read control to register file 
input   [7:0]    int_rd_data;    // data read from register file 
input   [7:0]    int_rd_data;    // data read from register file 
 
output                  int_req;                // bus access request signal 
 
input                   int_gnt;                // bus access grant signal 
 
 
// registered outputs
// registered outputs
reg     [7:0] tx_data;
reg     [7:0] tx_data;
reg new_tx_data;
reg new_tx_data;
reg     [AW-1:0] int_address;
reg     [AW-1:0] int_address;
reg     [7:0] int_wr_data;
reg     [7:0] int_wr_data;
reg int_write, int_read;
reg write_req, read_req, int_write, int_read;
 
 
// internal constants 
// internal constants 
// define characters used by the parser 
// define characters used by the parser 
`define CHAR_CR                 8'h0d
`define CHAR_CR                 8'h0d
`define CHAR_LF                 8'h0a
`define CHAR_LF                 8'h0a
`define CHAR_SPACE              8'h20
`define CHAR_SPACE              8'h20
`define CHAR_TAB                8'h09
`define CHAR_TAB                8'h09
`define CHAR_COMMA              8'h2C
`define CHAR_COMMA              8'h2C
`define CHAR_R_UP               8'h52
`define CHAR_R_UP               8'h52
`define CHAR_r_LO               8'h72
`define CHAR_r_LO               8'h72
`define CHAR_W_UP               8'h57
`define CHAR_W_UP               8'h57
`define CHAR_w_LO               8'h77
`define CHAR_w_LO               8'h77
`define CHAR_0                  8'h30
`define CHAR_0                  8'h30
`define CHAR_1                  8'h31
`define CHAR_1                  8'h31
`define CHAR_2                  8'h32
`define CHAR_2                  8'h32
`define CHAR_3                  8'h33
`define CHAR_3                  8'h33
`define CHAR_4                  8'h34
`define CHAR_4                  8'h34
`define CHAR_5                  8'h35
`define CHAR_5                  8'h35
`define CHAR_6                  8'h36
`define CHAR_6                  8'h36
`define CHAR_7                  8'h37
`define CHAR_7                  8'h37
`define CHAR_8                  8'h38
`define CHAR_8                  8'h38
`define CHAR_9                  8'h39
`define CHAR_9                  8'h39
`define CHAR_A_UP               8'h41
`define CHAR_A_UP               8'h41
`define CHAR_B_UP               8'h42
`define CHAR_B_UP               8'h42
`define CHAR_C_UP               8'h43
`define CHAR_C_UP               8'h43
`define CHAR_D_UP               8'h44
`define CHAR_D_UP               8'h44
`define CHAR_E_UP               8'h45
`define CHAR_E_UP               8'h45
`define CHAR_F_UP               8'h46
`define CHAR_F_UP               8'h46
`define CHAR_a_LO               8'h61
`define CHAR_a_LO               8'h61
`define CHAR_b_LO               8'h62
`define CHAR_b_LO               8'h62
`define CHAR_c_LO               8'h63
`define CHAR_c_LO               8'h63
`define CHAR_d_LO               8'h64
`define CHAR_d_LO               8'h64
`define CHAR_e_LO               8'h65
`define CHAR_e_LO               8'h65
`define CHAR_f_LO               8'h66
`define CHAR_f_LO               8'h66
 
 
// main (receive) state machine states 
// main (receive) state machine states 
`define MAIN_IDLE               4'b0000
`define MAIN_IDLE               4'b0000
`define MAIN_WHITE1             4'b0001
`define MAIN_WHITE1             4'b0001
`define MAIN_DATA               4'b0010
`define MAIN_DATA               4'b0010
`define MAIN_WHITE2             4'b0011
`define MAIN_WHITE2             4'b0011
`define MAIN_ADDR               4'b0100
`define MAIN_ADDR               4'b0100
`define MAIN_EOL                4'b0101
`define MAIN_EOL                4'b0101
// binary mode extension states 
// binary mode extension states 
`define MAIN_BIN_CMD    4'b1000
`define MAIN_BIN_CMD    4'b1000
`define MAIN_BIN_ADRH   4'b1001
`define MAIN_BIN_ADRH   4'b1001
`define MAIN_BIN_ADRL   4'b1010
`define MAIN_BIN_ADRL   4'b1010
`define MAIN_BIN_LEN    4'b1011
`define MAIN_BIN_LEN    4'b1011
`define MAIN_BIN_DATA   4'b1100
`define MAIN_BIN_DATA   4'b1100
 
 
// transmit state machine 
// transmit state machine 
`define TX_IDLE                 3'b000
`define TX_IDLE                 3'b000
`define TX_HI_NIB               3'b001
`define TX_HI_NIB               3'b001
`define TX_LO_NIB               3'b100
`define TX_LO_NIB               3'b100
`define TX_CHAR_CR              3'b101
`define TX_CHAR_CR              3'b101
`define TX_CHAR_LF              3'b110
`define TX_CHAR_LF              3'b110
 
 
// binary extension mode commands - the command is indicated by bits 5:4 of the command byte 
// binary extension mode commands - the command is indicated by bits 5:4 of the command byte 
`define BIN_CMD_NOP             2'b00
`define BIN_CMD_NOP             2'b00
`define BIN_CMD_READ    2'b01
`define BIN_CMD_READ    2'b01
`define BIN_CMD_WRITE   2'b10
`define BIN_CMD_WRITE   2'b10
 
 
// internal wires and registers 
// internal wires and registers 
reg [3:0] main_sm;                       // main state machine 
reg [3:0] main_sm;                       // main state machine 
reg read_op;                            // read operation flag 
reg read_op;                            // read operation flag 
reg write_op;                           // write operation flag 
reg write_op;                           // write operation flag 
reg data_in_hex_range;          // indicates that the received data is in the range of hex number 
reg data_in_hex_range;          // indicates that the received data is in the range of hex number 
reg [7:0] data_param;            // operation data parameter 
reg [7:0] data_param;            // operation data parameter 
reg [15:0] addr_param;           // operation address parameter 
reg [15:0] addr_param;           // operation address parameter 
reg [3:0] data_nibble;           // data nibble from received character 
reg [3:0] data_nibble;           // data nibble from received character 
reg read_done;                          // internally generated read done flag 
reg read_done;                          // internally generated read done flag 
reg read_done_s;                        // sampled read done 
reg read_done_s;                        // sampled read done 
reg [7:0] read_data_s;           // sampled read data 
reg [7:0] read_data_s;           // sampled read data 
reg [3:0] tx_nibble;             // nibble value for transmission 
reg [3:0] tx_nibble;             // nibble value for transmission 
reg [7:0] tx_char;                       // transmit byte from nibble to character conversion 
reg [7:0] tx_char;                       // transmit byte from nibble to character conversion 
reg [2:0] tx_sm;                 // transmit state machine 
reg [2:0] tx_sm;                 // transmit state machine 
reg s_tx_busy;                          // sampled tx_busy for falling edge detection 
reg s_tx_busy;                          // sampled tx_busy for falling edge detection 
reg bin_read_op;                        // binary mode read operation flag 
reg bin_read_op;                        // binary mode read operation flag 
reg bin_write_op;                       // binary mode write operation flag 
reg bin_write_op;                       // binary mode write operation flag 
reg addr_auto_inc;                      // address auto increment mode 
reg addr_auto_inc;                      // address auto increment mode 
reg send_stat_flag;                     // send status flag 
reg send_stat_flag;                     // send status flag 
reg [7:0] bin_byte_count;        // binary mode byte counter 
reg [7:0] bin_byte_count;        // binary mode byte counter 
wire bin_last_byte;                     // last byte flag indicates that the current byte in the command is the last 
wire bin_last_byte;                     // last byte flag indicates that the current byte in the command is the last 
wire tx_end_p;                          // transmission end pulse 
wire tx_end_p;                          // transmission end pulse 
 
 
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
// module implementation 
// module implementation 
// main state machine 
// main state machine 
always @ (posedge clock or posedge reset)
always @ (posedge clock or posedge reset)
begin
begin
        if (reset)
        if (reset)
                main_sm <= `MAIN_IDLE;
                main_sm <= `MAIN_IDLE;
        else if (new_rx_data)
        else if (new_rx_data)
        begin
        begin
                case (main_sm)
                case (main_sm)
                        // wait for a read ('r') or write ('w') command 
                        // wait for a read ('r') or write ('w') command 
                        // binary extension - an all zeros byte enabled binary commands 
                        // binary extension - an all zeros byte enabled binary commands 
                        `MAIN_IDLE:
                        `MAIN_IDLE:
                                // check received character 
                                // check received character 
                                if (rx_data == 8'h0)
                                if (rx_data == 8'h0)
                                        // an all zeros received byte enters binary mode 
                                        // an all zeros received byte enters binary mode 
                                        main_sm <= `MAIN_BIN_CMD;
                                        main_sm <= `MAIN_BIN_CMD;
                                else if ((rx_data == `CHAR_r_LO) | (rx_data == `CHAR_R_UP))
                                else if ((rx_data == `CHAR_r_LO) | (rx_data == `CHAR_R_UP))
                                        // on read wait to receive only address field 
                                        // on read wait to receive only address field 
                                        main_sm <= `MAIN_WHITE2;
                                        main_sm <= `MAIN_WHITE2;
                                else if ((rx_data == `CHAR_w_LO) | (rx_data == `CHAR_W_UP))
                                else if ((rx_data == `CHAR_w_LO) | (rx_data == `CHAR_W_UP))
                                        // on write wait to receive data and address 
                                        // on write wait to receive data and address 
                                        main_sm <= `MAIN_WHITE1;
                                        main_sm <= `MAIN_WHITE1;
                                else if ((rx_data == `CHAR_CR) | (rx_data == `CHAR_LF))
                                else if ((rx_data == `CHAR_CR) | (rx_data == `CHAR_LF))
                                        // on new line sta in idle 
                                        // on new line sta in idle 
                                        main_sm <= `MAIN_IDLE;
                                        main_sm <= `MAIN_IDLE;
                                else
                                else
                                        // any other character wait to end of line (EOL)
                                        // any other character wait to end of line (EOL)
                                        main_sm <= `MAIN_EOL;
                                        main_sm <= `MAIN_EOL;
 
 
                        // wait for white spaces till first data nibble 
                        // wait for white spaces till first data nibble 
                        `MAIN_WHITE1:
                        `MAIN_WHITE1:
                                // wait in this case until any white space character is received. in any 
                                // wait in this case until any white space character is received. in any 
                                // valid character for data value switch to data state. a new line or carriage 
                                // valid character for data value switch to data state. a new line or carriage 
                                // return should reset the state machine to idle.
                                // return should reset the state machine to idle.
                                // any other character transitions the state machine to wait for EOL.
                                // any other character transitions the state machine to wait for EOL.
                                if ((rx_data == `CHAR_SPACE) | (rx_data == `CHAR_TAB))
                                if ((rx_data == `CHAR_SPACE) | (rx_data == `CHAR_TAB))
                                        main_sm <= `MAIN_WHITE1;
                                        main_sm <= `MAIN_WHITE1;
                                else if (data_in_hex_range)
                                else if (data_in_hex_range)
                                        main_sm <= `MAIN_DATA;
                                        main_sm <= `MAIN_DATA;
                                else if ((rx_data == `CHAR_CR) | (rx_data == `CHAR_LF))
                                else if ((rx_data == `CHAR_CR) | (rx_data == `CHAR_LF))
                                        main_sm <= `MAIN_IDLE;
                                        main_sm <= `MAIN_IDLE;
                                else
                                else
                                        main_sm <= `MAIN_EOL;
                                        main_sm <= `MAIN_EOL;
 
 
                        // receive data field 
                        // receive data field 
                        `MAIN_DATA:
                        `MAIN_DATA:
                                // wait while data in hex range. white space transition to wait white 2 state.
                                // wait while data in hex range. white space transition to wait white 2 state.
                                // CR and LF resets the state machine. any other value cause state machine to 
                                // CR and LF resets the state machine. any other value cause state machine to 
                                // wait til end of line.
                                // wait til end of line.
                                if (data_in_hex_range)
                                if (data_in_hex_range)
                                        main_sm <= `MAIN_DATA;
                                        main_sm <= `MAIN_DATA;
                                else if ((rx_data == `CHAR_SPACE) | (rx_data == `CHAR_TAB))
                                else if ((rx_data == `CHAR_SPACE) | (rx_data == `CHAR_TAB))
                                        main_sm <= `MAIN_WHITE2;
                                        main_sm <= `MAIN_WHITE2;
                                else if ((rx_data == `CHAR_CR) | (rx_data == `CHAR_LF))
                                else if ((rx_data == `CHAR_CR) | (rx_data == `CHAR_LF))
                                        main_sm <= `MAIN_IDLE;
                                        main_sm <= `MAIN_IDLE;
                                else
                                else
                                        main_sm <= `MAIN_EOL;
                                        main_sm <= `MAIN_EOL;
 
 
                        // wait for white spaces till first address nibble 
                        // wait for white spaces till first address nibble 
                        `MAIN_WHITE2:
                        `MAIN_WHITE2:
                                // similar to MAIN_WHITE1 
                                // similar to MAIN_WHITE1 
                                if ((rx_data == `CHAR_SPACE) | (rx_data == `CHAR_TAB))
                                if ((rx_data == `CHAR_SPACE) | (rx_data == `CHAR_TAB))
                                        main_sm <= `MAIN_WHITE2;
                                        main_sm <= `MAIN_WHITE2;
                                else if (data_in_hex_range)
                                else if (data_in_hex_range)
                                        main_sm <= `MAIN_ADDR;
                                        main_sm <= `MAIN_ADDR;
                                else if ((rx_data == `CHAR_CR) | (rx_data == `CHAR_LF))
                                else if ((rx_data == `CHAR_CR) | (rx_data == `CHAR_LF))
                                        main_sm <= `MAIN_IDLE;
                                        main_sm <= `MAIN_IDLE;
                                else
                                else
                                        main_sm <= `MAIN_EOL;
                                        main_sm <= `MAIN_EOL;
 
 
                        // receive address field 
                        // receive address field 
                        `MAIN_ADDR:
                        `MAIN_ADDR:
                                // similar to MAIN_DATA 
                                // similar to MAIN_DATA 
                                if (data_in_hex_range)
                                if (data_in_hex_range)
                                        main_sm <= `MAIN_ADDR;
                                        main_sm <= `MAIN_ADDR;
                                else if ((rx_data == `CHAR_CR) | (rx_data == `CHAR_LF))
                                else if ((rx_data == `CHAR_CR) | (rx_data == `CHAR_LF))
                                        main_sm <= `MAIN_IDLE;
                                        main_sm <= `MAIN_IDLE;
                                else
                                else
                                        main_sm <= `MAIN_EOL;
                                        main_sm <= `MAIN_EOL;
 
 
                        // wait to EOL                          
                        // wait to EOL                          
                        `MAIN_EOL:
                        `MAIN_EOL:
                                // wait for CR or LF to move back to idle 
                                // wait for CR or LF to move back to idle 
                                if ((rx_data == `CHAR_CR) | (rx_data == `CHAR_LF))
                                if ((rx_data == `CHAR_CR) | (rx_data == `CHAR_LF))
                                        main_sm <= `MAIN_IDLE;
                                        main_sm <= `MAIN_IDLE;
 
 
                        // binary extension 
                        // binary extension 
                        // wait for command - one byte 
                        // wait for command - one byte 
                        `MAIN_BIN_CMD:
                        `MAIN_BIN_CMD:
                                // check if command is a NOP command 
                                // check if command is a NOP command 
                                if (rx_data[5:4] == `BIN_CMD_NOP)
                                if (rx_data[5:4] == `BIN_CMD_NOP)
                                        // if NOP command then switch back to idle state 
                                        // if NOP command then switch back to idle state 
                                        main_sm <= `MAIN_IDLE;
                                        main_sm <= `MAIN_IDLE;
                                else
                                else
                                        // not a NOP command, continue receiving parameters 
                                        // not a NOP command, continue receiving parameters 
                                        main_sm <= `MAIN_BIN_ADRH;
                                        main_sm <= `MAIN_BIN_ADRH;
 
 
                        // wait for address parameter - two bytes 
                        // wait for address parameter - two bytes 
                        // high address byte 
                        // high address byte 
                        `MAIN_BIN_ADRH:
                        `MAIN_BIN_ADRH:
                                // switch to next state 
                                // switch to next state 
                                main_sm <= `MAIN_BIN_ADRL;
                                main_sm <= `MAIN_BIN_ADRL;
 
 
                        // low address byte 
                        // low address byte 
                        `MAIN_BIN_ADRL:
                        `MAIN_BIN_ADRL:
                                // switch to next state 
                                // switch to next state 
                                main_sm <= `MAIN_BIN_LEN;
                                main_sm <= `MAIN_BIN_LEN;
 
 
                        // wait for length parameter - one byte 
                        // wait for length parameter - one byte 
                        `MAIN_BIN_LEN:
                        `MAIN_BIN_LEN:
                                // check if write command else command reception ended 
                                // check if write command else command reception ended 
                                if (bin_write_op)
                                if (bin_write_op)
                                        // wait for write data 
                                        // wait for write data 
                                        main_sm <= `MAIN_BIN_DATA;
                                        main_sm <= `MAIN_BIN_DATA;
                                else
                                else
                                        // command reception has ended 
                                        // command reception has ended 
                                        main_sm <= `MAIN_IDLE;
                                        main_sm <= `MAIN_IDLE;
 
 
                        // on write commands wait for data till end of buffer as specified by length parameter 
                        // on write commands wait for data till end of buffer as specified by length parameter 
                        `MAIN_BIN_DATA:
                        `MAIN_BIN_DATA:
                                // if this is the last data byte then return to idle 
                                // if this is the last data byte then return to idle 
                                if (bin_last_byte)
                                if (bin_last_byte)
                                        main_sm <= `MAIN_IDLE;
                                        main_sm <= `MAIN_IDLE;
 
 
                        // go to idle 
                        // go to idle 
                        default:
                        default:
                                main_sm <= `MAIN_IDLE;
                                main_sm <= `MAIN_IDLE;
                endcase
                endcase
        end
        end
end
end
 
 
// indicates that the received data is in the range of hex number 
// indicates that the received data is in the range of hex number 
always @ (rx_data)
always @ (rx_data)
begin
begin
        if (((rx_data >= `CHAR_0   ) && (rx_data <= `CHAR_9   )) ||
        if (((rx_data >= `CHAR_0   ) && (rx_data <= `CHAR_9   )) ||
            ((rx_data >= `CHAR_A_UP) && (rx_data <= `CHAR_F_UP)) ||
            ((rx_data >= `CHAR_A_UP) && (rx_data <= `CHAR_F_UP)) ||
            ((rx_data >= `CHAR_a_LO) && (rx_data <= `CHAR_f_LO)))
            ((rx_data >= `CHAR_a_LO) && (rx_data <= `CHAR_f_LO)))
                data_in_hex_range <= 1'b1;
                data_in_hex_range <= 1'b1;
        else
        else
                data_in_hex_range <= 1'b0;
                data_in_hex_range <= 1'b0;
end
end
 
 
// read operation flag 
// read operation flag 
always @ (posedge clock or posedge reset)
always @ (posedge clock or posedge reset)
begin
begin
        if (reset)
        if (reset)
                read_op <= 1'b0;
                read_op <= 1'b0;
        else if ((main_sm == `MAIN_IDLE) && new_rx_data)
        else if ((main_sm == `MAIN_IDLE) && new_rx_data)
        begin
        begin
                // the read operation flag is set when a read command is received in idle state and cleared 
                // the read operation flag is set when a read command is received in idle state and cleared 
                // if any other character is received during that state.
                // if any other character is received during that state.
                if ((rx_data == `CHAR_r_LO) | (rx_data == `CHAR_R_UP))
                if ((rx_data == `CHAR_r_LO) | (rx_data == `CHAR_R_UP))
                        read_op <= 1'b1;
                        read_op <= 1'b1;
                else
                else
                        read_op <= 1'b0;
                        read_op <= 1'b0;
        end
        end
end
end
 
 
// write operation flag 
// write operation flag 
always @ (posedge clock or posedge reset)
always @ (posedge clock or posedge reset)
begin
begin
        if (reset)
        if (reset)
                write_op <= 1'b0;
                write_op <= 1'b0;
        else if ((main_sm == `MAIN_IDLE) & new_rx_data)
        else if ((main_sm == `MAIN_IDLE) & new_rx_data)
        begin
        begin
                // the write operation flag is set when a write command is received in idle state and cleared 
                // the write operation flag is set when a write command is received in idle state and cleared 
                // if any other character is received during that state.
                // if any other character is received during that state.
                if ((rx_data == `CHAR_w_LO) | (rx_data == `CHAR_W_UP))
                if ((rx_data == `CHAR_w_LO) | (rx_data == `CHAR_W_UP))
                        write_op <= 1'b1;
                        write_op <= 1'b1;
                else
                else
                        write_op <= 1'b0;
                        write_op <= 1'b0;
        end
        end
end
end
 
 
// binary mode read operation flag 
// binary mode read operation flag 
always @ (posedge clock or posedge reset)
always @ (posedge clock or posedge reset)
begin
begin
        if (reset)
        if (reset)
                bin_read_op <= 1'b0;
                bin_read_op <= 1'b0;
        else if ((main_sm == `MAIN_BIN_CMD) && new_rx_data && (rx_data[5:4] == `BIN_CMD_READ))
        else if ((main_sm == `MAIN_BIN_CMD) && new_rx_data && (rx_data[5:4] == `BIN_CMD_READ))
                // read command is started on reception of a read command 
                // read command is started on reception of a read command 
                bin_read_op <= 1'b1;
                bin_read_op <= 1'b1;
        else if (bin_read_op && tx_end_p && bin_last_byte)
        else if (bin_read_op && tx_end_p && bin_last_byte)
                // read command ends on transmission of the last byte read 
                // read command ends on transmission of the last byte read 
                bin_read_op <= 1'b0;
                bin_read_op <= 1'b0;
end
end
 
 
// binary mode write operation flag 
// binary mode write operation flag 
always @ (posedge clock or posedge reset)
always @ (posedge clock or posedge reset)
begin
begin
        if (reset)
        if (reset)
                bin_write_op <= 1'b0;
                bin_write_op <= 1'b0;
        else if ((main_sm == `MAIN_BIN_CMD) && new_rx_data && (rx_data[5:4] == `BIN_CMD_WRITE))
        else if ((main_sm == `MAIN_BIN_CMD) && new_rx_data && (rx_data[5:4] == `BIN_CMD_WRITE))
                // write command is started on reception of a write command 
                // write command is started on reception of a write command 
                bin_write_op <= 1'b1;
                bin_write_op <= 1'b1;
        else if ((main_sm == `MAIN_BIN_DATA) && new_rx_data && bin_last_byte)
        else if ((main_sm == `MAIN_BIN_DATA) && new_rx_data && bin_last_byte)
                bin_write_op <= 1'b0;
                bin_write_op <= 1'b0;
end
end
 
 
// send status flag - used only in binary extension mode 
// send status flag - used only in binary extension mode 
always @ (posedge clock or posedge reset)
always @ (posedge clock or posedge reset)
begin
begin
        if (reset)
        if (reset)
                send_stat_flag <= 1'b0;
                send_stat_flag <= 1'b0;
        else if ((main_sm == `MAIN_BIN_CMD) && new_rx_data)
        else if ((main_sm == `MAIN_BIN_CMD) && new_rx_data)
        begin
        begin
                // check if a status byte should be sent at the end of the command 
                // check if a status byte should be sent at the end of the command 
                if (rx_data[0] == 1'b1)
                if (rx_data[0] == 1'b1)
                        send_stat_flag <= 1'b1;
                        send_stat_flag <= 1'b1;
                else
                else
                        send_stat_flag <= 1'b0;
                        send_stat_flag <= 1'b0;
        end
        end
end
end
 
 
// address auto increment - used only in binary extension mode 
// address auto increment - used only in binary extension mode 
always @ (posedge clock or posedge reset)
always @ (posedge clock or posedge reset)
begin
begin
        if (reset)
        if (reset)
                addr_auto_inc <= 1'b0;
                addr_auto_inc <= 1'b0;
        else if ((main_sm == `MAIN_BIN_CMD) && new_rx_data)
        else if ((main_sm == `MAIN_BIN_CMD) && new_rx_data)
        begin
        begin
                // check if address should be automatically incremented or not. 
                // check if address should be automatically incremented or not. 
                // Note that when rx_data[1] is set, address auto increment is disabled. 
                // Note that when rx_data[1] is set, address auto increment is disabled. 
                if (rx_data[1] == 1'b0)
                if (rx_data[1] == 1'b0)
                        addr_auto_inc <= 1'b1;
                        addr_auto_inc <= 1'b1;
                else
                else
                        addr_auto_inc <= 1'b0;
                        addr_auto_inc <= 1'b0;
        end
        end
end
end
 
 
// operation data parameter 
// operation data parameter 
always @ (posedge clock or posedge reset)
always @ (posedge clock or posedge reset)
begin
begin
        if (reset)
        if (reset)
                data_param <= 8'h0;
                data_param <= 8'h0;
        else if ((main_sm == `MAIN_WHITE1) & new_rx_data & data_in_hex_range)
        else if ((main_sm == `MAIN_WHITE1) & new_rx_data & data_in_hex_range)
                data_param <= {4'h0, data_nibble};
                data_param <= {4'h0, data_nibble};
        else if ((main_sm == `MAIN_DATA) & new_rx_data & data_in_hex_range)
        else if ((main_sm == `MAIN_DATA) & new_rx_data & data_in_hex_range)
                data_param <= {data_param[3:0], data_nibble};
                data_param <= {data_param[3:0], data_nibble};
end
end
 
 
// operation address parameter 
// operation address parameter 
always @ (posedge clock or posedge reset)
always @ (posedge clock or posedge reset)
begin
begin
        if (reset)
        if (reset)
                addr_param <= 0;
                addr_param <= 0;
        else if ((main_sm == `MAIN_WHITE2) & new_rx_data & data_in_hex_range)
        else if ((main_sm == `MAIN_WHITE2) & new_rx_data & data_in_hex_range)
                addr_param <= {12'b0, data_nibble};
                addr_param <= {12'b0, data_nibble};
        else if ((main_sm == `MAIN_ADDR) & new_rx_data & data_in_hex_range)
        else if ((main_sm == `MAIN_ADDR) & new_rx_data & data_in_hex_range)
                addr_param <= {addr_param[11:0], data_nibble};
                addr_param <= {addr_param[11:0], data_nibble};
        // binary extension 
        // binary extension 
        else if (main_sm == `MAIN_BIN_ADRH)
        else if (main_sm == `MAIN_BIN_ADRH)
                addr_param[15:8] <= rx_data;
                addr_param[15:8] <= rx_data;
        else if (main_sm == `MAIN_BIN_ADRL)
        else if (main_sm == `MAIN_BIN_ADRL)
                addr_param[7:0] <= rx_data;
                addr_param[7:0] <= rx_data;
end
end
 
 
// binary mode command byte counter is loaded with the length parameter and counts down to zero.
// binary mode command byte counter is loaded with the length parameter and counts down to zero.
// NOTE: a value of zero for the length parameter indicates a command of 256 bytes.
// NOTE: a value of zero for the length parameter indicates a command of 256 bytes.
always @ (posedge clock or posedge reset)
always @ (posedge clock or posedge reset)
begin
begin
        if (reset)
        if (reset)
                bin_byte_count <= 8'b0;
                bin_byte_count <= 8'b0;
        else if ((main_sm == `MAIN_BIN_LEN) && new_rx_data)
        else if ((main_sm == `MAIN_BIN_LEN) && new_rx_data)
                bin_byte_count <= rx_data;
                bin_byte_count <= rx_data;
        else if ((bin_write_op && (main_sm == `MAIN_BIN_DATA) && new_rx_data) ||
        else if ((bin_write_op && (main_sm == `MAIN_BIN_DATA) && new_rx_data) ||
                         (bin_read_op && tx_end_p))
                         (bin_read_op && tx_end_p))
                // byte counter is updated on every new data received in write operations and for every 
                // byte counter is updated on every new data received in write operations and for every 
                // byte transmitted for read operations.
                // byte transmitted for read operations.
                bin_byte_count <= bin_byte_count - 1;
                bin_byte_count <= bin_byte_count - 1;
end
end
// last byte in command flag 
// last byte in command flag 
assign bin_last_byte = (bin_byte_count == 8'h01) ? 1'b1 : 1'b0;
assign bin_last_byte = (bin_byte_count == 8'h01) ? 1'b1 : 1'b0;
 
 
// internal write control and data 
// internal write control and data 
always @ (posedge clock or posedge reset)
always @ (posedge clock or posedge reset)
begin
begin
        if (reset)
        if (reset)
        begin
        begin
 
                write_req <= 1'b0;
                int_write <= 1'b0;
                int_write <= 1'b0;
                int_wr_data <= 0;
                int_wr_data <= 0;
        end
        end
        else if (write_op && (main_sm == `MAIN_ADDR) && new_rx_data && !data_in_hex_range)
        else if (write_op && (main_sm == `MAIN_ADDR) && new_rx_data && !data_in_hex_range)
        begin
        begin
                int_write <= 1'b1;
                write_req <= 1'b1;
                int_wr_data <= data_param;
                int_wr_data <= data_param;
        end
        end
        // binary extension mode 
        // binary extension mode 
        else if (bin_write_op && (main_sm == `MAIN_BIN_DATA) && new_rx_data)
        else if (bin_write_op && (main_sm == `MAIN_BIN_DATA) && new_rx_data)
        begin
        begin
                int_write <= 1'b1;
                write_req <= 1'b1;
                int_wr_data <= rx_data;
                int_wr_data <= rx_data;
        end
        end
 
        else if (int_gnt && write_req)
 
        begin
 
                // set internal bus write and clear the write request flag 
 
                int_write <= 1'b1;
 
                write_req <= 1'b0;
 
        end
        else
        else
                int_write <= 1'b0;
                int_write <= 1'b0;
end
end
 
 
// internal read control 
// internal read control 
always @ (posedge clock or posedge reset)
always @ (posedge clock or posedge reset)
begin
begin
        if (reset)
        if (reset)
 
        begin
                int_read <= 1'b0;
                int_read <= 1'b0;
 
                read_req <= 1'b0;
 
        end
        else if (read_op && (main_sm == `MAIN_ADDR) && new_rx_data && !data_in_hex_range)
        else if (read_op && (main_sm == `MAIN_ADDR) && new_rx_data && !data_in_hex_range)
                int_read <= 1'b1;
                read_req <= 1'b1;
        // binary extension 
        // binary extension 
        else if (bin_read_op && (main_sm == `MAIN_BIN_LEN) && new_rx_data)
        else if (bin_read_op && (main_sm == `MAIN_BIN_LEN) && new_rx_data)
                // the first read request is issued on reception of the length byte 
                // the first read request is issued on reception of the length byte 
                int_read <= 1'b1;
                read_req <= 1'b1;
        else if (bin_read_op && tx_end_p && !bin_last_byte)
        else if (bin_read_op && tx_end_p && !bin_last_byte)
                // the next read requests are issued after the previous read value was transmitted and 
                // the next read requests are issued after the previous read value was transmitted and 
                // this is not the last byte to be read.
                // this is not the last byte to be read.
 
                read_req <= 1'b1;
 
        else if (int_gnt && read_req)
 
        begin
 
                // set internal bus read and clear the read request flag 
                int_read <= 1'b1;
                int_read <= 1'b1;
 
                read_req <= 1'b0;
 
        end
        else
        else
                int_read <= 1'b0;
                int_read <= 1'b0;
end
end
 
 
 
// external request signal is active on read or write request 
 
assign int_req = write_req | read_req;
 
 
// internal address 
// internal address 
always @ (posedge clock or posedge reset)
always @ (posedge clock or posedge reset)
begin
begin
        if (reset)
        if (reset)
                int_address <= 0;
                int_address <= 0;
        else if ((main_sm == `MAIN_ADDR) && new_rx_data && !data_in_hex_range)
        else if ((main_sm == `MAIN_ADDR) && new_rx_data && !data_in_hex_range)
                int_address <= addr_param[AW-1:0];
                int_address <= addr_param[AW-1:0];
        // binary extension 
        // binary extension 
        else if ((main_sm == `MAIN_BIN_LEN) && new_rx_data)
        else if ((main_sm == `MAIN_BIN_LEN) && new_rx_data)
                // sample address parameter on reception of length byte 
                // sample address parameter on reception of length byte 
                int_address <= addr_param[AW-1:0];
                int_address <= addr_param[AW-1:0];
        else if (addr_auto_inc &&
        else if (addr_auto_inc &&
                         ((bin_read_op && tx_end_p && !bin_last_byte) ||
                         ((bin_read_op && tx_end_p && !bin_last_byte) ||
//                        (bin_write_op && (main_sm == `MAIN_BIN_DATA) && new_rx_data)))
 
                          (bin_write_op && int_write)))
                          (bin_write_op && int_write)))
                // address is incremented on every read or write if enabled 
                // address is incremented on every read or write if enabled 
                int_address <= int_address + 1;
                int_address <= int_address + 1;
end
end
 
 
// read done flag and sampled data read 
// read done flag and sampled data read 
always @ (posedge clock or posedge reset)
always @ (posedge clock or posedge reset)
begin
begin
        if (reset) begin
        if (reset) begin
                read_done <= 1'b0;
                read_done <= 1'b0;
                read_done_s <= 1'b0;
                read_done_s <= 1'b0;
                read_data_s <= 8'h0;
                read_data_s <= 8'h0;
        end
        end
        else
        else
        begin
        begin
                // read done flag 
                // read done flag 
                if (int_read)
                if (int_read)
                        read_done <= 1'b1;
                        read_done <= 1'b1;
                else
                else
                        read_done <= 1'b0;
                        read_done <= 1'b0;
 
 
                // sampled read done 
                // sampled read done 
                read_done_s <= read_done;
                read_done_s <= read_done;
 
 
                // sampled data read 
                // sampled data read 
                if (read_done)
                if (read_done)
                        read_data_s <= int_rd_data;
                        read_data_s <= int_rd_data;
        end
        end
end
end
 
 
// transmit state machine and control 
// transmit state machine and control 
always @ (posedge clock or posedge reset)
always @ (posedge clock or posedge reset)
begin
begin
        if (reset) begin
        if (reset) begin
                tx_sm <= `TX_IDLE;
                tx_sm <= `TX_IDLE;
                tx_data <= 8'h0;
                tx_data <= 8'h0;
                new_tx_data <= 1'b0;
                new_tx_data <= 1'b0;
        end
        end
        else
        else
                case (tx_sm)
                case (tx_sm)
                        // wait for read done indication 
                        // wait for read done indication 
                        `TX_IDLE:
                        `TX_IDLE:
                                // on end of every read operation check how the data read should be transmitted 
                                // on end of every read operation check how the data read should be transmitted 
                                // according to read type: ascii or binary.
                                // according to read type: ascii or binary.
                                if (read_done_s)
                                if (read_done_s)
                                        // on binary mode read transmit byte value 
                                        // on binary mode read transmit byte value 
                                        if (bin_read_op)
                                        if (bin_read_op)
                                        begin
                                        begin
                                                // note that there is no need to change state 
                                                // note that there is no need to change state 
                                                tx_data <= read_data_s;
                                                tx_data <= read_data_s;
                                                new_tx_data <= 1'b1;
                                                new_tx_data <= 1'b1;
                                        end
                                        end
                                        else
                                        else
                                        begin
                                        begin
                                                tx_sm <= `TX_HI_NIB;
                                                tx_sm <= `TX_HI_NIB;
                                                tx_data <= tx_char;
                                                tx_data <= tx_char;
                                                new_tx_data <= 1'b1;
                                                new_tx_data <= 1'b1;
                                        end
                                        end
                                // check if status byte should be transmitted 
                                // check if status byte should be transmitted 
                                else if ((send_stat_flag && bin_read_op && tx_end_p && bin_last_byte) ||        // end of read command 
                                else if ((send_stat_flag && bin_read_op && tx_end_p && bin_last_byte) ||        // end of read command 
                                        (send_stat_flag && bin_write_op && new_rx_data && bin_last_byte) ||     // end of write command 
                                        (send_stat_flag && bin_write_op && new_rx_data && bin_last_byte) ||     // end of write command 
                                        ((main_sm == `MAIN_BIN_CMD) && new_rx_data && (rx_data[5:4] == `BIN_CMD_NOP)))  // NOP 
                                        ((main_sm == `MAIN_BIN_CMD) && new_rx_data && (rx_data[5:4] == `BIN_CMD_NOP)))  // NOP 
                                begin
                                begin
                                        // send status byte - currently a constant 
                                        // send status byte - currently a constant 
                                        tx_data <= 8'h5a;
                                        tx_data <= 8'h5a;
                                        new_tx_data <= 1'b1;
                                        new_tx_data <= 1'b1;
                                end
                                end
                                else
                                else
                                        new_tx_data <= 1'b0;
                                        new_tx_data <= 1'b0;
 
 
                        // wait for transmit to end 
                        // wait for transmit to end 
                        `TX_HI_NIB:
                        `TX_HI_NIB:
                                if (tx_end_p)
                                if (tx_end_p)
                                begin
                                begin
                                        tx_sm <= `TX_LO_NIB;
                                        tx_sm <= `TX_LO_NIB;
                                        tx_data <= tx_char;
                                        tx_data <= tx_char;
                                        new_tx_data <= 1'b1;
                                        new_tx_data <= 1'b1;
                                end
                                end
                                else
                                else
                                        new_tx_data <= 1'b0;
                                        new_tx_data <= 1'b0;
 
 
                        // wait for transmit to end 
                        // wait for transmit to end 
                        `TX_LO_NIB:
                        `TX_LO_NIB:
                                if (tx_end_p)
                                if (tx_end_p)
                                begin
                                begin
                                        tx_sm <= `TX_CHAR_CR;
                                        tx_sm <= `TX_CHAR_CR;
                                        tx_data <= `CHAR_CR;
                                        tx_data <= `CHAR_CR;
                                        new_tx_data <= 1'b1;
                                        new_tx_data <= 1'b1;
                                end
                                end
                                else
                                else
                                        new_tx_data <= 1'b0;
                                        new_tx_data <= 1'b0;
 
 
                        // wait for transmit to end 
                        // wait for transmit to end 
                        `TX_CHAR_CR:
                        `TX_CHAR_CR:
                                if (tx_end_p)
                                if (tx_end_p)
                                begin
                                begin
                                        tx_sm <= `TX_CHAR_LF;
                                        tx_sm <= `TX_CHAR_LF;
                                        tx_data <= `CHAR_LF;
                                        tx_data <= `CHAR_LF;
                                        new_tx_data <= 1'b1;
                                        new_tx_data <= 1'b1;
                                end
                                end
                                else
                                else
                                        new_tx_data <= 1'b0;
                                        new_tx_data <= 1'b0;
 
 
                        // wait for transmit to end 
                        // wait for transmit to end 
                        `TX_CHAR_LF:
                        `TX_CHAR_LF:
                                begin
                                begin
                                        if (tx_end_p)
                                        if (tx_end_p)
                                                tx_sm <= `TX_IDLE;
                                                tx_sm <= `TX_IDLE;
                                        // clear tx new data flag 
                                        // clear tx new data flag 
                                        new_tx_data <= 1'b0;
                                        new_tx_data <= 1'b0;
                                end
                                end
 
 
                        // return to idle 
                        // return to idle 
                        default:
                        default:
                                tx_sm <= `TX_IDLE;
                                tx_sm <= `TX_IDLE;
                endcase
                endcase
end
end
 
 
// select the nibble to the nibble to character conversion 
// select the nibble to the nibble to character conversion 
always @ (tx_sm or read_data_s)
always @ (tx_sm or read_data_s)
begin
begin
        case (tx_sm)
        case (tx_sm)
                `TX_IDLE:               tx_nibble = read_data_s[7:4];
                `TX_IDLE:               tx_nibble = read_data_s[7:4];
                `TX_HI_NIB:             tx_nibble = read_data_s[3:0];
                `TX_HI_NIB:             tx_nibble = read_data_s[3:0];
                default:                tx_nibble = read_data_s[7:4];
                default:                tx_nibble = read_data_s[7:4];
        endcase
        endcase
end
end
 
 
// sampled tx_busy 
// sampled tx_busy 
always @ (posedge clock or posedge reset)
always @ (posedge clock or posedge reset)
begin
begin
        if (reset)
        if (reset)
                s_tx_busy <= 1'b0;
                s_tx_busy <= 1'b0;
        else
        else
                s_tx_busy <= tx_busy;
                s_tx_busy <= tx_busy;
end
end
// tx end pulse 
// tx end pulse 
assign tx_end_p = ~tx_busy & s_tx_busy;
assign tx_end_p = ~tx_busy & s_tx_busy;
 
 
// character to nibble conversion 
// character to nibble conversion 
always @ (rx_data)
always @ (rx_data)
begin
begin
        case (rx_data)
        case (rx_data)
                `CHAR_0:                                data_nibble = 4'h0;
                `CHAR_0:                                data_nibble = 4'h0;
                `CHAR_1:                                data_nibble = 4'h1;
                `CHAR_1:                                data_nibble = 4'h1;
                `CHAR_2:                                data_nibble = 4'h2;
                `CHAR_2:                                data_nibble = 4'h2;
                `CHAR_3:                                data_nibble = 4'h3;
                `CHAR_3:                                data_nibble = 4'h3;
                `CHAR_4:                                data_nibble = 4'h4;
                `CHAR_4:                                data_nibble = 4'h4;
                `CHAR_5:                                data_nibble = 4'h5;
                `CHAR_5:                                data_nibble = 4'h5;
                `CHAR_6:                                data_nibble = 4'h6;
                `CHAR_6:                                data_nibble = 4'h6;
                `CHAR_7:                                data_nibble = 4'h7;
                `CHAR_7:                                data_nibble = 4'h7;
                `CHAR_8:                                data_nibble = 4'h8;
                `CHAR_8:                                data_nibble = 4'h8;
                `CHAR_9:                                data_nibble = 4'h9;
                `CHAR_9:                                data_nibble = 4'h9;
                `CHAR_A_UP, `CHAR_a_LO: data_nibble = 4'ha;
                `CHAR_A_UP, `CHAR_a_LO: data_nibble = 4'ha;
                `CHAR_B_UP, `CHAR_b_LO: data_nibble = 4'hb;
                `CHAR_B_UP, `CHAR_b_LO: data_nibble = 4'hb;
                `CHAR_C_UP, `CHAR_c_LO: data_nibble = 4'hc;
                `CHAR_C_UP, `CHAR_c_LO: data_nibble = 4'hc;
                `CHAR_D_UP, `CHAR_d_LO: data_nibble = 4'hd;
                `CHAR_D_UP, `CHAR_d_LO: data_nibble = 4'hd;
                `CHAR_E_UP, `CHAR_e_LO: data_nibble = 4'he;
                `CHAR_E_UP, `CHAR_e_LO: data_nibble = 4'he;
                `CHAR_F_UP, `CHAR_f_LO: data_nibble = 4'hf;
                `CHAR_F_UP, `CHAR_f_LO: data_nibble = 4'hf;
                default:                                data_nibble = 4'hf;
                default:                                data_nibble = 4'hf;
        endcase
        endcase
end
end
 
 
// nibble to character conversion 
// nibble to character conversion 
always @ (tx_nibble)
always @ (tx_nibble)
begin
begin
        case (tx_nibble)
        case (tx_nibble)
                4'h0:   tx_char = `CHAR_0;
                4'h0:   tx_char = `CHAR_0;
                4'h1:   tx_char = `CHAR_1;
                4'h1:   tx_char = `CHAR_1;
                4'h2:   tx_char = `CHAR_2;
                4'h2:   tx_char = `CHAR_2;
                4'h3:   tx_char = `CHAR_3;
                4'h3:   tx_char = `CHAR_3;
                4'h4:   tx_char = `CHAR_4;
                4'h4:   tx_char = `CHAR_4;
                4'h5:   tx_char = `CHAR_5;
                4'h5:   tx_char = `CHAR_5;
                4'h6:   tx_char = `CHAR_6;
                4'h6:   tx_char = `CHAR_6;
                4'h7:   tx_char = `CHAR_7;
                4'h7:   tx_char = `CHAR_7;
                4'h8:   tx_char = `CHAR_8;
                4'h8:   tx_char = `CHAR_8;
                4'h9:   tx_char = `CHAR_9;
                4'h9:   tx_char = `CHAR_9;
                4'ha:   tx_char = `CHAR_A_UP;
                4'ha:   tx_char = `CHAR_A_UP;
                4'hb:   tx_char = `CHAR_B_UP;
                4'hb:   tx_char = `CHAR_B_UP;
                4'hc:   tx_char = `CHAR_C_UP;
                4'hc:   tx_char = `CHAR_C_UP;
                4'hd:   tx_char = `CHAR_D_UP;
                4'hd:   tx_char = `CHAR_D_UP;
                4'he:   tx_char = `CHAR_E_UP;
                4'he:   tx_char = `CHAR_E_UP;
                default: tx_char = `CHAR_F_UP;
                default: tx_char = `CHAR_F_UP;
        endcase
        endcase
end
end
 
 
endmodule
endmodule
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//                                              Th.. Th.. Th.. Thats all folks !!!
//                                              Th.. Th.. Th.. Thats all folks !!!
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.