📄 rs232_syscon_v.htm
字号:
m1_next_state <= m1_get_qty_field;
store_qty <= 1;
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
</PRE></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -