verilog 不用内部时钟 LED 控制

 

module led( clk_40mhz, rst_n, led_1, spi_cs_n, spi_clk, spi_mosi, spi_miso, gpio_95, gpio_94, gpio_93 );

input clk_40mhz;  // pin62
input rst_n;      // pin64
output led_1;     // pin13

output gpio_95;   // pin95
output gpio_94;   // pin94
output gpio_93;   // pin93

// spi signal
input spi_cs_n; // pin97
input spi_clk;  // pin98 必须用 可以接入时钟的 引脚
input spi_mosi; // pin96
output spi_miso; // pin2

// 变量区
reg led_reg = 1'd0;

reg [7:0] rx_cnt = 8'd0;
reg [7:0] rx_cmd = 8'd0;
reg [7:0] rx_data0 = 8'd0;
reg [7:0] rx_data1 = 8'd0;
reg [7:0] rx_data2 = 8'd0;
reg [7:0] rx_data3 = 8'd0;

(* syn_preserve = "true" *)
reg rx_done = 1'd0; // 上升沿 用于传递接收命令已经完成

// reg [4:0] tx_cnt = 5'd31;
// reg [31:0] tx_reg = 32'h5A59445A;
// reg spi_miso_reg = 1'd0;
//reg out_flag = 1'd0;

reg gpio_93_reg = 1'd0;

// 接收计数 控制逻辑
always @(posedge spi_clk or posedge spi_cs_n or negedge rst_n) begin
    if(!rst_n)
        rx_cnt <= 8'd0;
    else if(spi_cs_n)
        rx_cnt <= 8'd0;
    else
        rx_cnt <= rx_cnt + 8'd1;
end

// 接收数据控制逻辑
always @(posedge spi_clk or negedge rst_n) begin
    if(!rst_n) begin
        rx_cmd  <= 8'd0;
        rx_data0 <= 8'd0;
        rx_data1 <= 8'd0;
        rx_data2 <= 8'd0;
        rx_data3 <= 8'd0;
    end else begin
        case(rx_cnt)
            8'd0: rx_cmd[7] <= spi_mosi;
            8'd1: rx_cmd[6] <= spi_mosi;
            8'd2: rx_cmd[5] <= spi_mosi;
            8'd3: rx_cmd[4] <= spi_mosi;
            8'd4: rx_cmd[3] <= spi_mosi;
            8'd5: rx_cmd[2] <= spi_mosi;
            8'd6: rx_cmd[1] <= spi_mosi;
            8'd7: rx_cmd[0] <= spi_mosi;

            8'd8: rx_data0[7] <= spi_mosi;
            8'd9: rx_data0[6] <= spi_mosi;
            8'd10: rx_data0[5] <= spi_mosi;
            8'd11: rx_data0[4] <= spi_mosi;
            8'd12: rx_data0[3] <= spi_mosi;
            8'd13: rx_data0[2] <= spi_mosi;
            8'd14: rx_data0[1] <= spi_mosi;
            8'd15: rx_data0[0] <= spi_mosi;

            8'd16: rx_data1[7] <= spi_mosi;
            8'd17: rx_data1[6] <= spi_mosi;
            8'd18: rx_data1[5] <= spi_mosi;
            8'd19: rx_data1[4] <= spi_mosi;
            8'd20: rx_data1[3] <= spi_mosi;
            8'd21: rx_data1[2] <= spi_mosi;
            8'd22: rx_data1[1] <= spi_mosi;
            8'd23: rx_data1[0] <= spi_mosi;

            8'd24: rx_data2[7] <= spi_mosi;
            8'd25: rx_data2[6] <= spi_mosi;
            8'd26: rx_data2[5] <= spi_mosi;
            8'd27: rx_data2[4] <= spi_mosi;
            8'd28: rx_data2[3] <= spi_mosi;
            8'd29: rx_data2[2] <= spi_mosi;
            8'd30: rx_data2[1] <= spi_mosi;
            8'd31: rx_data2[0] <= spi_mosi;

            8'd32: rx_data3[7] <= spi_mosi;
            8'd33: rx_data3[6] <= spi_mosi;
            8'd34: rx_data3[5] <= spi_mosi;
            8'd35: rx_data3[4] <= spi_mosi;
            8'd36: rx_data3[3] <= spi_mosi;
            8'd37: rx_data3[2] <= spi_mosi;
            8'd38: rx_data3[1] <= spi_mosi;
            8'd39: rx_data3[0] <= spi_mosi;
//             default: rx_data[0] <= spi_mosi;
        endcase
    end
end

// 检测 data 是否接收完成, 并给出上升沿信号,传递信息
always @(negedge spi_clk) begin
    if( rx_cnt == 8'd8 ) begin
        rx_done <= 1'd1;
        gpio_93_reg <=1'd1;  // 信号测试
    end else begin
        rx_done <= 1'd0;
        gpio_93_reg <=1'd0;  // 信号测试
    end
end

// 接收数据处理
always @(posedge rx_done or negedge rst_n ) begin
    if(!rst_n) begin
        led_reg <= 1'd0;
    end else if(rx_done) begin
        case(rx_cmd)
            8'h55: led_reg <= 1'd1; // LED OFF
            8'hAA: led_reg <= 1'd0; // LED ON
        endcase
    end
end


assign led_1 = led_reg;

// 输出信号观察
assign gpio_95 = spi_cs_n;
assign gpio_94 = spi_clk;
assign gpio_93 = gpio_93_reg;

// spi slave output
// assign spi_miso = spi_miso_reg;
assign spi_miso = 1'd0;

endmodule

注意:  之前没有 rx_data0 ,  就会优化,  rx_cnt  加不到 8 , 不会触发 rx_done 信号!!!!!!!!!!!!

波形如下:

image

 

posted on 2025-08-03 17:18  所长  阅读(13)  评论(0)    收藏  举报

导航