|
工程文件,基于Libero SOC v11.6
其中的串口核心模块用的是CoreUART
verilog源码:
///////////////////////////////////////////////////////////////////////////////////////////////////
// Company: <Name>
//
// File: uart_paser.v
// File history:
// <V1.0>: <2015/12/13>: <Comments>
//
// Description:
//
// <Description here>
//
// Targeted device: <Family::ProASIC3> <Die::A3P060> <Package::100 VQFP>
// Author: <Kingreat>
//
///////////////////////////////////////////////////////////////////////////////////////////////////
//`timescale <time_units> / <precision>
module uart_paser( clk, rst_n,
wen, txrdy, tx_data,
oen, rxrdy, rx_data,
ena_cnt, q,
io_ctrl, io_stat);
// modules inputs and outputs
input clk;
input rst_n;
output wen;
input txrdy; // signs that transmitter is ready
output[7:0] tx_data; // data byte to transmit
output oen;
input rxrdy; // Signs that receive is ready
input[7:0] rx_data; // data byte received
output[9:0] io_ctrl; // Control electromagnet[6..0] and cylinder_v_pwr[7]
// and chippos_pwr[8] and photo_pwr[9]
input[10:0] io_stat; // State of electromagnet[6..0] and cylinder_h[7]
// and cylinder_v[8] and chippos[9] and overlight[10]
input[31:0] q;
output ena_cnt;
// registered outputs [tx]
reg wen;
reg s_txrdy; // sampled txrdy for rising edge detection
reg[7:0] tx_data;
reg[3:0] tx_sm; // transmit state machine
reg[7:0] tx_packet_len;
reg[7:0] tx_packet_type;
reg[7:0] tx_packet_styp;
reg[7:0] tx_packet_end;
reg[15:0] tx_csum_calc;
// registered outputs [rx]
reg oen;
reg s_rxrdy1; // sampled rxrdy for rising edge detection
reg s_rxrdy2;
reg new_rx_data; // signs that a new byte was received
reg[3:0] rx_sm;
reg[7:0] rx_packet_len;
reg[7:0] rx_packet_type;
reg[7:0] rx_packet_styp;
reg[7:0] rx_packet_chan;
reg[7:0] rx_packet_end;
reg[15:0] rx_csum_read;
reg[15:0] rx_csum_calc;
// registered outputs [photo counter]
reg[31:0] curr_value; // current photo counter value
reg[31:0] last_value; // last photo counter value
reg ena_cnt;
reg start_cnt_flag;
reg[24:0] timer;
// registered outputs [IO]
reg[9:0] io_ctrl;
wire tx_end; // transmission end pulse
// (transmit packet) state machine states
`define TX_IDLE 4'b0000
`define TX_PLEN 4'b0001
`define TX_TYPE 4'b0010
`define TX_STYP 4'b0011
`define TX_SUMH 4'b0100
`define TX_SUML 4'b0101
`define TX_PEND 4'b0110
`define TX_EOL 4'b0111
`define TX_IOSL 4'b1000
`define TX_IOSH 4'b1001
`define TX_CNT4 4'b1010
`define TX_CNT3 4'b1011
`define TX_CNT2 4'b1100
`define TX_CNT1 4'b1101
`define TX_OLIT 4'b1110
// (receive packet) state machine states
`define RX_IDLE 4'b0000
`define RX_PLEN 4'b0001
`define RX_TYPE 4'b0010
`define RX_STYP 4'b0011
`define RX_DATA 4'b0100
`define RX_SUMH 4'b0101
`define RX_SUML 4'b0110
`define RX_PEND 4'b0111
// packet type
`define TYPE_MOTION_CTRL 8'h4d // 'M'
`define TYPE_MOTION_STAT 8'h6d // 'm'
`define TYPE_COUNTER_CTRL 8'h43 // 'C'
`define TYPE_COUNTER_STAT 8'h63 // 'c'
// packet sub type
`define STYP_GDPACKET 8'h00 /* Get IO status */
`define STYP_EMUP 8'h01 /* electromagnet up command*/
`define STYP_EMDN 8'h02 /* electromagnet down command */
`define STYP_EMRST 8'h03 /* Reset all electromagnet command */
`define STYP_STARCNT 8'h01 /* Start counter */
`define STYP_STOPCNT 8'h02 /* Stop counter */
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0) begin
s_rxrdy1 <= 1'b1;
s_rxrdy2 <= 1'b1;
end else begin
s_rxrdy1 <= rxrdy;
s_rxrdy2 <= s_rxrdy1;
end
end
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0) begin
oen <= 1'b1;
end else begin
if ((s_rxrdy1 == 1'b1) && (s_rxrdy2 == 1'b1) && (new_rx_data == 1'b1)) begin
oen <= 1'b0;
end else begin
oen <= 1'b1;
end
end
end
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
new_rx_data <= 1'b0;
else begin
if ((s_rxrdy1 == 1'b1) && (s_rxrdy2 == 1'b0)) begin
// rx_data <= datain;
new_rx_data <= 1'b1;
end else begin
new_rx_data <= 1'b0;
end
end
end
// Receive state machine states
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0) begin
rx_sm <= `RX_IDLE;
end else begin
if (new_rx_data) begin
case (rx_sm)
`RX_IDLE:
if (rx_data == 8'h02) begin
rx_sm <= `RX_PLEN;
end else begin
rx_sm <= `RX_IDLE;
end
`RX_PLEN:
if ((rx_data == 8'h07) || (rx_data == 8'h08))
rx_sm <= `RX_TYPE;
else
rx_sm <= `RX_IDLE;
`RX_TYPE:
if ((rx_data == `TYPE_MOTION_CTRL) ||
(rx_data == `TYPE_MOTION_STAT) ||
(rx_data == `TYPE_COUNTER_CTRL) ||
(rx_data == `TYPE_COUNTER_STAT))
rx_sm <= `RX_STYP;
else
rx_sm <= `RX_IDLE;
`RX_STYP:
rx_sm <= `RX_DATA;
`RX_DATA:
if (rx_packet_len == 8'h08)
rx_sm <= `RX_SUMH;
else if (rx_packet_len == 8'h07)
rx_sm <= `RX_SUML;
`RX_SUMH:
rx_sm <= `RX_SUML;
`RX_SUML:
rx_sm <= `RX_PEND;
`RX_PEND:
rx_sm <= `RX_IDLE;
default:
rx_sm <= `RX_IDLE;
endcase
end
end
end
// Calc checksum for per byte
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0) begin
rx_csum_calc <= 16'h0000;
rx_packet_len <= 8'h00;
rx_packet_type <= 8'h00;
rx_packet_styp <= 8'h00;
rx_packet_chan <= 8'h00;
end else begin
if ((rx_sm == `RX_IDLE) && new_rx_data) begin
rx_csum_calc <= rx_data;
end else if ((rx_sm == `RX_PLEN) && new_rx_data) begin
rx_packet_len <= rx_data;
rx_csum_calc <= rx_csum_calc + rx_data;
end else if ((rx_sm == `RX_TYPE) && new_rx_data) begin
rx_packet_type <= rx_data;
rx_csum_calc <= rx_csum_calc + rx_data;
end else if ((rx_sm == `RX_STYP) && new_rx_data) begin
rx_packet_styp <= rx_data;
rx_csum_calc <= rx_csum_calc + rx_data;
end else if ((rx_sm == `RX_DATA) && new_rx_data && (rx_packet_len == 8'h08)) begin
rx_packet_chan <= rx_data;
rx_csum_calc <= rx_csum_calc + rx_data;
end
end
end
// Read checksum form packet received
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
rx_csum_read <= 16'h0000;
else begin
if ((rx_sm == `RX_DATA) && new_rx_data && (rx_packet_len == 8'h07)) begin
rx_csum_read[15:8] <= rx_data;
end else if ((rx_sm == `RX_SUMH) && new_rx_data) begin
rx_csum_read[15:8] <= rx_data;
end else if ((rx_sm == `RX_SUML) && new_rx_data) begin
rx_csum_read[7:0] <= rx_data;
end
end
end
// Command handle received
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0) begin
io_ctrl[6:0] <= 7'b1111111; // EM7 .. EM1
start_cnt_flag <= 1'b0;
// ena_cnt <= 1'b0;
end else begin
if ((rx_sm == `RX_PEND) && new_rx_data) begin
if ((rx_data == 8'h03) && (rx_csum_read == rx_csum_calc)) begin
// Setup electromagnet to up
if ((rx_packet_type == `TYPE_MOTION_CTRL) &&
(rx_packet_styp == `STYP_EMUP) &&
(rx_packet_len == 8'h08)) begin
io_ctrl[6:0] <= io_ctrl[6:0] & (~(7'd1 << (rx_packet_chan - 8'h01)));
// Setup electromagnet to down
end else if ((rx_packet_type == `TYPE_MOTION_CTRL) &&
(rx_packet_styp == `STYP_EMDN) &&
(rx_packet_len == 8'h08)) begin
io_ctrl[6:0] <= io_ctrl[6:0] | (7'd1 << (rx_packet_chan - 8'h01));
// Setup all electromagnet to down
end else if ((rx_packet_type == `TYPE_MOTION_CTRL) &&
(rx_packet_styp == `STYP_EMRST) &&
(rx_packet_len == 8'h07)) begin
io_ctrl[6:0] <= 7'b1111111;
// Start photo counter
end else if ((rx_packet_type == `TYPE_COUNTER_CTRL) &&
(rx_packet_styp == `STYP_STARCNT) &&
(rx_packet_len == 8'h07)) begin
start_cnt_flag <= 1'b1;
//ena_cnt <= 1'b1;
// Stop photo counter
end else if ((rx_packet_type == `TYPE_COUNTER_CTRL) &&
(rx_packet_styp == `STYP_STOPCNT) &&
(rx_packet_len == 8'h07)) begin
start_cnt_flag <= 1'b0;
end
end
end
end
end
// sampled txrdy
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 0) begin
s_txrdy <= 1'b1;
end else begin
s_txrdy <= txrdy;
end
end
// tx end pulse
assign tx_end = txrdy & ~s_txrdy;
// Transmit state machine states
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0) begin
tx_sm <= `TX_IDLE;
wen <= 1'b1;
tx_data <= 8'h0;
tx_csum_calc <= 16'h0000;
tx_packet_len <= 8'h00;
tx_packet_type <= 8'h00;
tx_packet_styp <= 8'h00;
tx_packet_end <= 8'h00;
io_ctrl[7] <= 1'b1; // Power on cylinder_v, 1=off, 0=on.
io_ctrl[8] <= 1'b1; // Power on chip postion, 1=off, 0=on.
io_ctrl[9] <= 1'b1; // Power on photo counter, 1=on, 0=off.
end else begin
case (tx_sm)
`TX_IDLE:
// Send io status
if ((rx_sm == `RX_PEND) && new_rx_data &&
(rx_data == 8'h03) && (rx_csum_read == rx_csum_calc) &&
(rx_packet_type == `TYPE_MOTION_CTRL) &&
(rx_packet_styp == `STYP_GDPACKET) &&
(start_cnt_flag == 1'b0)) begin // When measuring, can not get status.
tx_data <= 8'h02;
wen <= 1'b0;
tx_sm <= `TX_PLEN;
tx_csum_calc <= 8'h02;
tx_packet_len <= 8'h09;
tx_packet_type <= `TYPE_MOTION_CTRL;
tx_packet_styp <= 8'h00;
tx_packet_end <= 8'h03;
io_ctrl[7] <= 1'b0; // Power on cylinder_v, 1=off, 0=on.
io_ctrl[8] <= 1'b0; // Power on chip postion, 1=off, 0=on.
end else if ((start_cnt_flag == 1'b1) && (timer == 25'd25000000)) begin
tx_data <= 8'h02;
wen <= 1'b0;
tx_sm <= `TX_PLEN;
tx_csum_calc <= 8'h02;
tx_packet_len <= 8'h0c;
tx_packet_type <= `TYPE_COUNTER_CTRL;
tx_packet_styp <= 8'h00;
tx_packet_end <= 8'h03;
end else
tx_sm <= `TX_IDLE;
`TX_PLEN:
if (tx_end) begin
tx_data <= tx_packet_len;
wen <= 1'b0;
tx_sm <= `TX_TYPE;
tx_csum_calc <= tx_csum_calc + tx_packet_len;
end else begin
wen <= 1'b1;
end
`TX_TYPE:
if (tx_end) begin
tx_data <= tx_packet_type;
wen <= 1'b0;
tx_sm <= `TX_STYP;
tx_csum_calc <= tx_csum_calc + tx_packet_type;
end else begin
wen <= 1'b1;
end
`TX_STYP:
if (tx_end) begin
if (tx_packet_len == 8'h07) begin
tx_data <= tx_packet_styp;
wen <= 1'b0;
tx_sm <= `TX_SUMH;
tx_csum_calc <= tx_csum_calc + tx_packet_styp;
end else if (tx_packet_len == 8'h09) begin
tx_data <= tx_packet_styp;
wen <= 1'b0;
tx_sm <= `TX_IOSL;
tx_csum_calc <= tx_csum_calc + tx_packet_styp;
end else if (tx_packet_len == 8'h0c) begin
tx_data <= tx_packet_styp;
wen <= 1'b0;
tx_sm <= `TX_OLIT;
tx_csum_calc <= tx_csum_calc + tx_packet_styp;
end else begin
tx_sm <= `TX_EOL;
end
end else begin
wen <= 1'b1;
end
`TX_IOSL:
if (tx_end) begin
tx_data <= io_stat[6:0];
wen <= 1'b0;
tx_sm <= `TX_IOSH;
tx_csum_calc <= tx_csum_calc + io_stat[6:0];
end else begin
wen <= 1'b1;
end
`TX_IOSH:
if (tx_end) begin
tx_data <= (~io_stat[9:7] & 8'h07);
wen <= 1'b0;
tx_sm <= `TX_SUMH;
tx_csum_calc <= tx_csum_calc + (~io_stat[9:7] & 8'h07);
end else begin
wen <= 1'b1;
end
`TX_OLIT:
if (tx_end) begin
tx_data <= (~io_stat[10] & 8'h01); // ~io_stat[10]: 1=over light
wen <= 1'b0;
tx_sm <= `TX_CNT4;
tx_csum_calc <= tx_csum_calc + (~io_stat[10] & 8'h01);
end else begin
wen <= 1'b1;
end
`TX_CNT4:
if (tx_end) begin
tx_data <= curr_value[31:24];
wen <= 1'b0;
tx_sm <= `TX_CNT3;
tx_csum_calc <= tx_csum_calc + curr_value[31:24];
end else begin
wen <= 1'b1;
end
`TX_CNT3:
if (tx_end) begin
tx_data <= curr_value[23:16];
wen <= 1'b0;
tx_sm <= `TX_CNT2;
tx_csum_calc <= tx_csum_calc + curr_value[23:16];
end else begin
wen <= 1'b1;
end
`TX_CNT2:
if (tx_end) begin
tx_data <= curr_value[15:8];
wen <= 1'b0;
tx_sm <= `TX_CNT1;
tx_csum_calc <= tx_csum_calc + curr_value[15:8];
end else begin
wen <= 1'b1;
end
`TX_CNT1:
if (tx_end) begin
tx_data <= curr_value[7:0];
wen <= 1'b0;
tx_sm <= `TX_SUMH;
tx_csum_calc <= tx_csum_calc + curr_value[7:0];
end else begin
wen <= 1'b1;
end
`TX_SUMH:
if (tx_end) begin
tx_data <= tx_csum_calc[15:8];
wen <= 1'b0;
tx_sm <= `TX_SUML;
end else begin
wen <= 1'b1;
end
`TX_SUML:
if (tx_end) begin
tx_data <= tx_csum_calc[7:0];
wen <= 1'b0;
tx_sm <= `TX_PEND;
end else begin
wen <= 1'b1;
end
`TX_PEND:
if (tx_end) begin
tx_data <= tx_packet_end;
wen <= 1'b0;
tx_sm <= `TX_EOL;
end else begin
wen <= 1'b1;
end
`TX_EOL:
if (tx_end) begin
tx_sm <= `TX_IDLE;
io_ctrl[7] <= 1'b1; // Power on cylinder_v, 1=off, 0=on.
io_ctrl[8] <= 1'b1; // Power on chip postion, 1=off, 0=on.
end else
wen <= 1'b1;
default:
tx_sm <= `TX_IDLE;
endcase
end
end
// photo counter
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0) begin
timer <= 25'd0;
ena_cnt <= 1'b0;
curr_value <= 32'd0;
end else begin
if (start_cnt_flag) begin
if (timer == 25'd25000000) begin
ena_cnt <= 1'b0;
timer <= 25'd0;
curr_value <= q;
end else begin
timer <= timer + 1'b1;
ena_cnt <= 1'b1;
end
end else begin
timer <= 25'd0;
ena_cnt <= 1'b0;
end
end
end
endmodule
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|