⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rs232_syscon.v

📁 This build is for developing a "binary-to-BCD" converter for use in // displaying numerals in base-
💻 V
📖 第 1 页 / 共 4 页
字号:
          incr_cmd_ptr <= 1;
        end
        else if (char_is_whitespace || char_is_enter) begin  // Normal exit
          m1_next_state <= m1_start_execution;
        end
        else m1_next_state <= m1_qty_error_indicator;
      end

    // This state seeks to obtain master_bg_i, which grants the bus to
    // rs232_syscon.
    m1_start_execution :
      begin
        rs232_echo <= 1;           // Don't send message characters
        reset_watchdog <= 1;       // Reset the timer.
        reset_adr_offset <= 1;     // Reset the address offset.
        reset_rd_field_count <= 1; // Reset the rd_field_count.
        m1_next_state <= m1_request_bus;
      end

    m1_request_bus :
      begin
        rs232_echo <= 1;          // Don't send message characters
        master_br_o <= 1;         // Request the bus.
        if (master_bg_i) m1_next_state <= m1_bus_granted;
        else if (watchdog_timer_done) begin
          m1_next_state <= m1_bg_error_indicator;
        end
        else m1_next_state <= m1_request_bus;
      end

    m1_bus_granted :
      begin
        rs232_echo <= 1;          // Don't send message characters
        master_br_o <= 1;         // Keep holding the bus
        reset_watchdog <= 1;      // Reset the timer.
        if (adr_offset != qty_sr) m1_next_state <= m1_execute;
        else m1_next_state <= m1_send_ok;
      end

    // This single state does reset/write/read depending upon the value
    // contained in "command"!
    m1_execute :
      begin
        rs232_echo <= 1;          // Don't send message characters
        master_br_o <= 1;         // Keep holding the bus
        stb_l <= 1'b1;            // Show that a bus cycle is happening
        case (command)            // Assert the appropriate signals
          `CMD_I : rst_o <= 1;
          `CMD_R : capture_dat <= ack_i;
          `CMD_W : we_l <= 1;
          default: ;
        endcase
        if (watchdog_timer_done || err_i) begin
          m1_next_state <= m1_ack_error_indicator;
        end
        else if (ack_i
                 && (command == `CMD_R)
                 && (rd_field_count == 0)
                 )
        begin
          m1_next_state <= m1_rd_send_adr_sr; // Leads to a new address line.
          reset_rd_digit_count <= 1;
          incr_adr_offset <= 1;               // move to the next address
        end
        else if (ack_i && (command == `CMD_R)) begin
          m1_next_state <= m1_rd_send_dat_sr; // Leads to a new data field.
          reset_rd_digit_count <= 1;
          reset_msg_offset <= 1;
          incr_adr_offset <= 1;             // move to the next address
        end
        else if (ack_i) begin
          m1_next_state <= m1_bus_granted;  // continue to the next cycle
          incr_adr_offset <= 1;             // move to the next address
        end
        else m1_next_state <= m1_execute;
      end

    m1_rd_send_adr_sr :
      begin
        msg_base <= {1'b0,rd_adr_sr[`NIBBLE_SIZE*ADR_DIGITS_PP-1:
                                    `NIBBLE_SIZE*(ADR_DIGITS_PP-1)]};
        if ((rd_digit_count == ADR_DIGITS_PP-1) && rs232_tx_load) begin
          m1_next_state <= m1_rd_send_separator;
          reset_msg_offset <= 1;
        end
        else if (rs232_tx_load) begin
          shift_rd_adr <= 1;
          incr_rd_digit_count <= 1;
          m1_next_state <= m1_rd_send_adr_sr;
        end
        else m1_next_state <= m1_rd_send_adr_sr;
      end

    m1_rd_send_separator :
      begin
        msg_base <= 5'b10000;    // Address of the separator message
        incr_msg_offset <= rs232_tx_load;
        if ((msg_offset == 2) && rs232_tx_load)
        begin
          m1_next_state <= m1_rd_send_dat_sr;
          reset_rd_digit_count <= 1;
          reset_msg_offset <= 1;
        end
        else m1_next_state <= m1_rd_send_separator;
      end

    m1_rd_send_dat_sr :
      begin
        msg_base <= {1'b0,dat_sr[`NIBBLE_SIZE*DAT_DIGITS_PP-1:
                                 `NIBBLE_SIZE*(DAT_DIGITS_PP-1)]};
        if (
            (rd_digit_count == DAT_DIGITS_PP-1)
            && (rd_field_count == RD_FIELDS_PP-1)
            && rs232_tx_load
            )
        begin
          m1_next_state <= m1_rd_send_crlf;
          reset_rd_field_count <= 1;
        end
        else if ((rd_digit_count == DAT_DIGITS_PP-1) && rs232_tx_load) begin
          m1_next_state <= m1_rd_send_space;
          incr_rd_field_count <= 1;
        end
        else if (rs232_tx_load) begin
            store_dat <= 1;
            incr_rd_digit_count <= 1;
            m1_next_state <= m1_rd_send_dat_sr;
        end
        else m1_next_state <= m1_rd_send_dat_sr;
      end

    m1_rd_send_space :
      begin
        msg_base <= 5'b10000;    // Address of the space
        incr_msg_offset <= rs232_tx_load;
        if ((msg_offset == 0) && rs232_tx_load) begin
          m1_next_state <= m1_bus_granted;
          reset_msg_offset <= 1;
        end
        else m1_next_state <= m1_rd_send_space;
      end

    m1_rd_send_crlf :
      begin
        msg_base <= 5'b10111;     // Address of the cr/lf message
        incr_msg_offset <= rs232_tx_load;
        if ((msg_offset == 1) && rs232_tx_load) begin
          m1_next_state <= m1_bus_granted;
          reset_msg_offset <= 1;
        end
        else m1_next_state <= m1_rd_send_crlf;
      end

    default : m1_next_state <= m1_initial_state;
  endcase
end


// This is the counter for incrementing or loading the cmd_ptr
always @(posedge clk_i)
begin
  if (reset_i || reset_cmd_ptr) cmd_ptr <= 0;
  else if (decr_cmd_ptr) cmd_ptr <= cmd_ptr - 1;
  else if (incr_cmd_ptr) cmd_ptr <= cmd_ptr + 1;
end


// This is the command buffer writing section
always @(posedge clk_i)
begin
  if (rs232_echo && cmd_buffer_write) cmd_buffer[cmd_ptr] <= rs232_rx_char;
end
// This is the command buffer reading section
assign cmd_char = cmd_buffer[cmd_ptr];
assign lc_cmd_char = (cmd_buffer[cmd_ptr] | 8'h20); // lowercase



// These assigments are for detecting whether the cmd_char is
// anything of special interest.
assign char_is_enter = (cmd_char == 8'h0d);          // enter
assign char_is_whitespace = (
                                (cmd_char == 8'h20)  // space
                             || (cmd_char == 8'h09)  // tab
                             );
assign char_is_num = ((cmd_char>=8'h30)&&(cmd_char<=8'h39));
assign char_is_a_f = ((lc_cmd_char>=8'h61)&&(lc_cmd_char<=8'h66));
assign char_is_hex = ( char_is_num || char_is_a_f );
assign char_is_r = (lc_cmd_char == 8'h72); // "r"
assign char_is_w = (lc_cmd_char == 8'h77); // "w"
assign char_is_i = (lc_cmd_char == 8'h69); // "i"

assign hex_digit = char_is_num?cmd_char[3:0]:(cmd_char[3:0]+9);

// This is the command register.  It stores the type of command to execute.
// This is so that the state machine can parse address, data and qty
// into "generic" storage locations, and then when it executes the command,
// it refers back to this register in order to determine what type of
// operation to perform.

always @(posedge clk_i)
begin
  if (reset_i) command <= `CMD_0;
  else if (cmd_i) command <= `CMD_I;
  else if (cmd_r) command <= `CMD_R;
  else if (cmd_w) command <= `CMD_W;
end

// This is the "nibble" shift register for the address which is sent character
// by character to the user.  It is loaded each time the adr_offset is
// incremented, in order to save the previous address for use in printing
// to the user.
always @(posedge clk_i)
begin
  if (reset_i || reset_adr) rd_adr_sr <= 0;
  else if (incr_adr_offset) rd_adr_sr <= adr_ptr;
  else if (shift_rd_adr) begin
    rd_adr_sr[`NIBBLE_SIZE*ADR_DIGITS_PP-1:`NIBBLE_SIZE] <=
      rd_adr_sr[`NIBBLE_SIZE*(ADR_DIGITS_PP-1)-1:0];
    rd_adr_sr[`NIBBLE_SIZE-1:0] <= {`NIBBLE_SIZE{1'b0}};
  end
end

// These are the "nibble" shift registers.  They handle loading the
// hexadecimal digits from the command line.
always @(posedge clk_i)
begin
  if (reset_i || reset_adr) adr_sr <= 0;
  else if (store_adr) begin
    adr_sr[`NIBBLE_SIZE*ADR_DIGITS_PP-1:`NIBBLE_SIZE] <=
      adr_sr[`NIBBLE_SIZE*(ADR_DIGITS_PP-1)-1:0];
    adr_sr[`NIBBLE_SIZE-1:0] <= hex_digit;
  end
end

always @(posedge clk_i)
begin
  if (reset_i || reset_dat) dat_sr <= 0;
  else if (capture_dat) dat_sr <= dat_io;
  else if (store_dat) begin
    dat_sr[`NIBBLE_SIZE*DAT_DIGITS_PP-1:`NIBBLE_SIZE] <=
      dat_sr[`NIBBLE_SIZE*(DAT_DIGITS_PP-1)-1:0];
    dat_sr[`NIBBLE_SIZE-1:0] <= hex_digit;
  end
end

always @(posedge clk_i)
begin
  if (reset_i || reset_qty) qty_sr <= 0;
  else if (init_qty) qty_sr <= 1;
  else if (store_qty) begin
    qty_sr[`NIBBLE_SIZE*QTY_DIGITS_PP-1:`NIBBLE_SIZE] <=
      qty_sr[`NIBBLE_SIZE*(QTY_DIGITS_PP-1)-1:0];
    qty_sr[`NIBBLE_SIZE-1:0] <= hex_digit;
  end
end

// This is the rd_digit_count counter.  It is used for counting digits
// displayed of both the adr_sr and dat_sr, so it must be able to count up
// to the extent of the larger of the two...
always @(posedge clk_i)
begin
  if (reset_i || reset_rd_digit_count) rd_digit_count <= 0;
  else if (incr_rd_digit_count) rd_digit_count <= rd_digit_count + 1;
end

// This is the rd_field_count counter.  It is used for counting dat_sr fields
// displayed per line.
always @(posedge clk_i)
begin
  if (reset_i || reset_rd_field_count) rd_field_count <= 0;
  else if (incr_rd_field_count) rd_field_count <= rd_field_count + 1;
end


// This is the watchdog timer counter
// The watchdog timer is always "enabled" to operate.
always @(posedge clk_i)
begin
  if (reset_i || reset_watchdog) watchdog_timer_count <= 0;
  else if (~watchdog_timer_done)
    watchdog_timer_count <= watchdog_timer_count + 1;
end
assign watchdog_timer_done = (watchdog_timer_count==WATCHDOG_TIMER_VALUE_PP);


endmodule


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -