搜索
bottom↓
回复: 8

开源基于ACTEL的A3P060写的串口通讯程序[verilog]

[复制链接]

出0入0汤圆

发表于 2016-1-4 15:52:55 | 显示全部楼层 |阅读模式
工程文件,基于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周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2016-1-11 22:01:08 来自手机 | 显示全部楼层
mark           

出0入0汤圆

发表于 2016-1-15 16:52:37 | 显示全部楼层
正好我有这块板子,可能试试!

出0入0汤圆

发表于 2016-1-15 21:46:30 来自手机 | 显示全部楼层
我也有个 板子

出0入0汤圆

发表于 2018-4-22 13:41:32 | 显示全部楼层
若干年前,有公司推过这个FPGA板子,99元。

出0入0汤圆

发表于 2018-5-1 22:59:06 | 显示全部楼层
好贴支持

出0入0汤圆

发表于 2019-1-14 10:57:48 | 显示全部楼层
现在公司居然用了这个公司的片子

出0入0汤圆

发表于 2019-1-14 12:45:40 | 显示全部楼层
ACTEL的编译软件哪里能下载?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 00:13

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表