📄 rs232_syscon.v
字号:
reg store_qty; // Allows qty_sr to store hex_digit.
reg reset_adr; // Clears adr_sr
reg reset_dat; // Clears dat_sr
reg reset_qty; // Clears qty_sr
reg init_qty; // Sets qty_sr to 1
reg capture_dat; // Puts dat_io into dat_sr for later display.
// For the buses
wire [`NIBBLE_SIZE*ADR_DIGITS_PP-1:0] adr_ptr; // = adr_sr + adr_offset
reg stb_l; // "local" stb signal (to distinguish from stb_o)
reg we_l; // "local" we signal (to distinguish from we_o)
reg [`NIBBLE_SIZE*ADR_DIGITS_PP-1:0] rd_adr_sr; // sr for printing addresses
reg [`NIBBLE_SIZE*ADR_DIGITS_PP-1:0] adr_sr; // "nibble" shift register
reg [`NIBBLE_SIZE*DAT_DIGITS_PP-1:0] dat_sr; // "nibble" shift register
reg [`NIBBLE_SIZE*QTY_DIGITS_PP-1:0] qty_sr; // "nibble" shift register
reg [1:0] command;
reg [`NIBBLE_SIZE*QTY_DIGITS_PP-1:0] adr_offset; // counts from 0 to qty_sr
reg reset_adr_offset;
reg incr_adr_offset;
// For the command buffer
reg [CMD_PTR_BITS_PP-1:0] cmd_ptr; // Offset from start of command.
reg reset_cmd_ptr; // High == set command pointer to zero.
reg incr_cmd_ptr; // Used for "write port" side of the command buffer
reg decr_cmd_ptr; // Used for "write port" side of the command buffer
reg cmd_buffer_write;
reg [7:0] cmd_buffer [0:CMD_BUFFER_SIZE_PP-1];
wire [7:0] cmd_char;
wire [7:0] lc_cmd_char; // Lowercase version of cmd_char
// For the state machine
reg [4:0] m1_state;
reg [4:0] m1_next_state;
// For various counters
reg reset_rd_field_count;
reg reset_rd_digit_count;
reg incr_rd_field_count;
reg incr_rd_digit_count;
reg [RD_FIELD_COUNT_BITS_PP-1:0] rd_field_count; // "fields displayed"
reg [RD_DIGIT_COUNT_BITS_PP-1:0] rd_digit_count; // "digits displayed"
reg [WATCHDOG_TIMER_BITS_PP-1:0] watchdog_timer_count;
reg reset_watchdog;
// For the rs232 interface
wire serial_clk;
wire [2:0] rs232_rx_error;
wire rs232_tx_load;
wire rs232_tx_load_request;
wire rs232_rx_data_ready;
wire [7:0] rs232_rx_char;
wire [7:0] rs232_tx_char; // Either rs232_rx_char or msg_char
//--------------------------------------------------------------------------
// Instantiations
//--------------------------------------------------------------------------
// These defines are for the rs232 interface
`define START_BITS 1
`define DATA_BITS 8
`define STOP_BITS 1
`define CLOCK_FACTOR 8
// This module generates a serial BAUD clock automatically.
// The unit synchronizes on the carriage return character, so the user
// only needs to press the "enter" key for serial communications to start
// working, no matter what BAUD rate and clk_i frequency are used!
auto_baud_with_tracking #(
`CLOCK_FACTOR, // CLOCK_FACTOR_PP
16 // LOG2_MAX_COUNT_PP
)
clock_unit_2
(
.clk_i(clk_i),
.reset_i(reset_i),
.serial_dat_i(rs232_rxd_i),
.auto_baud_locked_o(),
.baud_clk_o(serial_clk)
);
// A transmitter, which asserts load_request at the end of the currently
// transmitted word. The tx_clk must be a "clock enable" (narrow positive
// pulse) which occurs at 16x the desired transmit rate. If load_request
// is connected directly to load, the unit will transmit continuously.
rs232tx #(
`START_BITS, // start_bits
`DATA_BITS, // data_bits
`STOP_BITS, // stop_bits (add intercharacter delay...)
`CLOCK_FACTOR // clock_factor
)
rs232_tx_block // instance name
(
.clk(clk_i),
.tx_clk(serial_clk),
.reset(reset_i),
.load(rs232_tx_load),
.data(rs232_tx_char),
.load_request(rs232_tx_load_request),
.txd(rs232_txd_o)
);
// A receiver, which asserts "word_ready" to indicate a received word.
// Asserting "read_word" will cause "word_ready" to go low again if it was high.
// The character is held in the output register, during the time the next
// character is coming in.
rs232rx #(
`START_BITS, // start_bits
`DATA_BITS, // data_bits
`STOP_BITS, // stop_bits
`CLOCK_FACTOR // clock_factor
)
rs232_rx_block // instance name
(
.clk(clk_i),
.rx_clk(serial_clk),
.reset(reset_i || (| rs232_rx_error)),
.rxd(rs232_rxd_i),
.read(rs232_tx_load),
.data(rs232_rx_char),
.data_ready(rs232_rx_data_ready),
.error_over_run(rs232_rx_error[0]),
.error_under_run(rs232_rx_error[1]),
.error_all_low(rs232_rx_error[2])
);
//`undef START_BITS
//`undef DATA_BITS
//`undef STOP_BITS
//`undef CLOCK_FACTOR
//--------------------------------------------------------------------------
// Module code
//--------------------------------------------------------------------------
assign adr_o = master_bg_i?adr_ptr:master_adr_i;
assign we_o = master_bg_i?we_l:master_we_i;
assign stb_o = master_bg_i?stb_l:master_stb_i;
assign dat_io = (master_bg_i && we_l && stb_l)?
dat_sr:{`NIBBLE_SIZE*DAT_DIGITS_PP{1'bZ}};
// Temporary
assign cyc_o = stb_o; // Separate cyc_o is not yet supported!
// This is the adress offset counter
always @(posedge clk_i)
begin
if (reset_i || reset_adr_offset) adr_offset <= 0;
else if (incr_adr_offset) adr_offset <= adr_offset + 1;
end
// This forms the adress pointer which is used on the bus.
assign adr_ptr = adr_sr + adr_offset;
// This is the ROM for the ASCII characters to be transmitted.
always @(msg_pointer)
begin
case (msg_pointer) // synthesis parallel_case
5'b00000 : msg_char <= 8'h30; // "0"; // Hexadecimal characters
5'b00001 : msg_char <= 8'h31; // "1";
5'b00010 : msg_char <= 8'h32; // "2";
5'b00011 : msg_char <= 8'h33; // "3";
5'b00100 : msg_char <= 8'h34; // "4";
5'b00101 : msg_char <= 8'h35; // "5";
5'b00110 : msg_char <= 8'h36; // "6";
5'b00111 : msg_char <= 8'h37; // "7";
5'b01000 : msg_char <= 8'h38; // "8";
5'b01001 : msg_char <= 8'h39; // "9";
5'b01010 : msg_char <= 8'h41; // "A"; // Address error indication
5'b01011 : msg_char <= 8'h42; // "B";
5'b01100 : msg_char <= 8'h43; // "C"; // Command error indication
5'b01101 : msg_char <= 8'h44; // "D"; // Data error indication
5'b01110 : msg_char <= 8'h45; // "E";
5'b01111 : msg_char <= 8'h46; // "F";
5'b10000 : msg_char <= 8'h20; // " "; // Space
5'b10001 : msg_char <= 8'h3A; // ":"; // Colon
5'b10010 : msg_char <= 8'h20; // " "; // Space
5'b10011 : msg_char <= 8'h3F; // "?"; // Parse error indication
5'b10100 : msg_char <= 8'h21; // "!"; // ack_i/err_i error indication
5'b10101 : msg_char <= 8'h4F; // "O"; // "All is well" message
5'b10110 : msg_char <= 8'h4B; // "K";
5'b10111 : msg_char <= 8'h0D; // Carriage return & line feed
5'b11000 : msg_char <= 8'h0A;
5'b11001 : msg_char <= 8'h2D; // "-"; // Command Prompt
5'b11010 : msg_char <= 8'h3E; // ">";
5'b11011 : msg_char <= 8'h20; // " ";
5'b11100 : msg_char <= 8'h51; // "Q"; // Quantity error indication
default : msg_char <= 8'h3D; // "=";
endcase
end
// This logic determines when to load a transmit character.
assign rs232_tx_load = rs232_echo?
(rs232_rx_data_ready && rs232_tx_load_request):rs232_tx_load_request;
// This is the counter for incrementing, decrementing or resetting the
// message pointer.
always @(posedge clk_i)
begin
if (reset_i || reset_msg_offset) msg_offset <= 0;
else if (incr_msg_offset) msg_offset <= msg_offset + 1;
end
assign msg_pointer = msg_offset + msg_base;
// This is the mux which selects whether to echo back the characters
// received (as during the entering of a command) or to send back response
// characters.
assign rs232_tx_char = (rs232_echo)?rs232_rx_char:msg_char;
// These assigments are for detecting whether the received rs232 character is
// anything of special interest.
assign rx_char_is_enter = (rs232_rx_char == 8'h0d);
assign rx_char_is_backspace = (rs232_rx_char == 8'h08);
// This is state machine m1. It handles receiving the command line, including
// backspaces, and prints error/response messages. It also parses and
// executes the commands.
// State register
always @(posedge clk_i)
begin : m1_state_register
if (reset_i) m1_state <= m1_initial_state; // perform reset for rest of system
else m1_state <= m1_next_state;
end
// State transition logic
always @(m1_state
or rx_char_is_enter
or rx_char_is_backspace
or msg_offset
or cmd_ptr
or rs232_tx_load
or char_is_whitespace
or char_is_hex
or char_is_enter
or char_is_i
or char_is_r
or char_is_w
or command
or master_bg_i
or watchdog_timer_done
or err_i
or ack_i
or adr_offset
or qty_sr
or dat_sr
or rd_adr_sr
or rd_field_count
or rd_digit_count
)
begin : m1_state_logic
// Default values for outputs. The individual states can override these.
msg_base <= 5'b0;
reset_msg_offset <= 0;
incr_msg_offset <= 0;
rs232_echo <= 0;
rst_o <= 0;
we_l <= 0;
stb_l <= 0;
cmd_buffer_write <= 0;
reset_cmd_ptr <= 0;
incr_cmd_ptr <= 0;
decr_cmd_ptr <= 0;
master_br_o <= 0;
cmd_r <= 0;
cmd_w <= 0;
cmd_i <= 0;
shift_rd_adr <= 0;
store_adr <= 0; // enables storing hex chars in adr_sr (shift)
store_dat <= 0; // enables storing hex chars in dat_sr (shift)
store_qty <= 0; // enables storing hex chars in qty_sr (shift)
reset_adr <= 0;
reset_dat <= 0;
reset_qty <= 0;
init_qty <= 0;
capture_dat <= 0; // enables capturing bus data in dat_sr (load)
incr_adr_offset <= 0;
reset_adr_offset <= 0;
reset_watchdog <= 0;
incr_rd_field_count <= 0;
incr_rd_digit_count <= 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -