diff --git a/spi_tx_rx/rx/rx_sram.v b/spi_tx_rx/rx/rx_sram.v new file mode 100644 index 0000000..aad0139 --- /dev/null +++ b/spi_tx_rx/rx/rx_sram.v @@ -0,0 +1,172 @@ +// Relese History +// Version Date Author Description +// 0.2 2024-06-14 ZYZ +//----------------------------------------------------------------------------------------------------------------- +// Keywords : receive data from spi_master,sent data to PC +// set reset to output Rdata_PC +//----------------------------------------------------------------------------------------------------------------- +// Parameter +// +//----------------------------------------------------------------------------------------------------------------- +// Purpose : +// +//----------------------------------------------------------------------------------------------------------------- +// Target Device: +// Tool versions: +//----------------------------------------------------------------------------------------------------------------- +// Reuse Issues +// Reset Strategy: +// Clock Domains: +// Critical Timing: +// Asynchronous I/F: +// Synthesizable (y/n): +// Other: +//-FHDR-------------------------------------------------------------------------------------------------------- + +module rx_sram( + input clk, + input rstn, + + (* mark_debug="true" *) input [31:0] din , + (* mark_debug="true" *) input din_vld , + (* mark_debug="true" *) input data_rden_rx, + (* mark_debug="true" *) output [31:0] Rdata_PC +); + +parameter width = 32 ; +parameter depth = 65536 ; + +//================================================= +function integer clog2(input integer depth); +begin + for(clog2=0;depth>0;clog2=clog2+1) + depth =depth>>1; +end +endfunction +//================================================= + +localparam aw = clog2(depth-1); + +//================================================= +//wr&rd address +(* mark_debug="true" *) reg [aw-1:0] cnta ; +(* mark_debug="true" *) reg [aw-1:0] cntb ; + +(* mark_debug="true" *) reg ena ; +(* mark_debug="true" *) reg enb ; +(* mark_debug="true" *) wire [31:0] doutb ; + +(* mark_debug="true" *) reg [31:0] din_reg; +always @(posedge clk or negedge rstn) + begin + if(!rstn ) begin + din_reg <= 1'b0; + end + else begin + din_reg <= din; + end + end + +(* mark_debug="true" *) reg data_rden_rx_reg; +always @(posedge clk or negedge rstn) + begin + if(!rstn) begin + data_rden_rx_reg <= 1'b0 ; + end + else begin + data_rden_rx_reg <= data_rden_rx ; + end +end + +//addra addrb +always @(posedge clk or negedge rstn) + begin + if(!rstn) begin + cnta <= 'h0 ; + end + else if(ena) begin + cnta <= cnta + 'b1; + end + else + cnta <= cnta ; + end + +always @(posedge clk or negedge rstn) + begin + if(!rstn ) begin + cntb <= 'h0; + end + else if(enb) begin + cntb <= cntb + 'b1; + end + else begin + cntb <= cntb; + end + end + +//enable +always @(posedge clk or negedge rstn) + begin + if(!rstn ) begin + ena <= 1'b0; + end + else begin + ena <= din_vld; + end + end +always @(posedge clk or negedge rstn) + begin + if(!rstn) begin + enb <= 1'b0 ; + end + else if(data_rden_rx_reg & (cntb <= cnta - 1'b1))begin + enb <= 1'b1 ; + end + else begin + enb <= 1'b0 ; + end + end + + +reg [31:0] Rdata_PC_reg; +always @(posedge clk or negedge rstn) + begin + if(!rstn ) begin + Rdata_PC_reg <= 32'b0; + end + else begin + Rdata_PC_reg <= doutb; + end + end +assign Rdata_PC = Rdata_PC_reg; +/* +blk_mem_gen_0 blk_mem_gen_0_inst( + .clka(clk), + .ena(1'b1), + .wea(ena), + .dina(Rdata_reg), + .addra(cnta), + + .clkb(clk), + .enb(enb), + .doutb(doutb), + .addrb(cntb) +); +*/ + +spram_model #( + .width(width), + .depth(depth) +)spram_inst( + .clka(clk), + .ena(~ena), + .dina(din_reg), + .addra(cnta), + + .clkb(clk), + .enb(~enb), + .doutb(doutb), + .addrb(cntb) +); + +endmodule diff --git a/spi_tx_rx/spi_master/AxiSpi.v b/spi_tx_rx/spi_master/AxiSpi.v new file mode 100644 index 0000000..76c44d8 --- /dev/null +++ b/spi_tx_rx/spi_master/AxiSpi.v @@ -0,0 +1,219 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2024/04/03 15:36:03 +// Design Name: +// Module Name: AxiSpi +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module AxiSpi( + input clk, + input reset, + input WR, // write en + input RD, // read en + //input [7 : 0] Wlength, // д³¤¶È + //input [7 : 0] Rlength, // ¶Á³¤¶È + input [31 : 0] WADDR, // дµØÖ· + input [31 : 0] RADDR, // ¶ÁµØÖ· + + (* KEEP="TRUE"*) input [31 : 0] DIN, + input WVALID, // дÊý¾ÝµÄvalid + input cmd_s, // Ö¡¸ñʽ¿ØÖÆ×Ö + input [4 : 0] chirpID, + input [31 : 0] Nlen, + + (* KEEP="TRUE"*) output WREADY, // ¿ÉÒÔдÊý + (* KEEP="TRUE"*) output RREADY, // ¿ÉÒÔ¶ÁÊý + // read data from spi slave, need to send to axi + (* KEEP="TRUE"*) output RVALID, + (* KEEP="TRUE"*) output [31 : 0] RDATA, + + // interface to spi slave + input spi_slave_bit, + + (* KEEP="TRUE"*) output ss, + (* KEEP="TRUE"*) output spi_clk, + (* KEEP="TRUE"*) output spi_master_bit + ); + +// ÎÞÂÛ¶Áд¶¼ÒªÍ¨¹ýдspi slave µÄ·½Ê½£¬Ö»ÊÇдµÄÖ¸Áͬ +//axi_slave_mem axi_slave_mem_u( +// .clk1(sys_clk), // write clk +// .reset(!sys_rst_n), +// .WR(WR1), +// .RD(1'b0), +// .ADDR_WR(ADDR_WR), +// .ADDR_RD(ADDR_RD), +// .DIN(DIN), +// .cmd_s(1'b0), + +// .DVALID(DVALID1), +// .DOUT(DOUT1), +// .ValidRange(ValidRange1) +// ); + +//axi_slave_mem axi_slave_mem_u2( // ¶Á +// .clk1(sys_clk), // write clk +// // .clk2(sys_clk), // read clk +// .reset(!sys_rst_n), +// .WR(WR2), +// .RD(1'b1), +// .ADDR_WR(ADDR_WR2), +// .ADDR_RD(ADDR_WR2), +// .DIN(DIN2), +// .cmd_s(1'b0), + +// .DVALID(DVALID2), +// .DOUT(DOUT2), +// .ValidRange(ValidRange2) +//); + +reg WR_c; // ¶Á»¹ÊÇдµÄÑ¡Ôñ +always@(posedge clk) +begin + if(reset) + begin + WR_c <= 1'b0; + end + else if(WR_c == 1'b0) // д״̬ÏÂÖ±µ½¶ÁÖ¸Áîµ½À´ÔÙ·´×ª + begin + if(RD) + WR_c <= 1'b1; + end + else // ¶Á״̬ÏÂÖ±µ½Ð´Ö¸Áîµ½À´ÔÙ·´×ª + begin + if(WR) + WR_c <= 1'b0; + end +end +// ÓÉÓÚWR_cµÄÔ­Òò£¬ËùÓÐÊäÈë¶¼ÒªºóÑÓÒ»¸öclk²ÅÄܺÍWR_c¶ÔÆë +reg WR_r; +reg RD_r; +reg [31 : 0] WADDR_r; +reg [31 : 0] RADDR_r; +reg [31 : 0] DIN_r; +reg cmd_sr; +always@(posedge clk) +begin + if(reset) + begin + WADDR_r <= 32'b0; + RADDR_r <= 32'b0; + DIN_r <= 32'b0; + cmd_sr <= 1'b0; + WR_r <= 1'b0; + RD_r <= 1'b0; + end + else + begin + WADDR_r <= WADDR; + RADDR_r <= RADDR; + DIN_r <= DIN ; + cmd_sr <= cmd_s; + WR_r <= WR; + RD_r <= RD; + end +end +wire DVALID; +wire [7 : 0] DOUT; +wire ValidRange; +wire [31 : 0] data_spi_32; +wire WR_mem; +assign WR_mem = WR_r || RD_r; // ÎÞÂÛ¶Á»¹ÊÇд£¬¶¼ÐèÒª¶Áд +axi_slave_mem axi_slave_mem_u( // µØÖ·Ö»»á¸øÊ×µØÖ·£¬ºóÃæÐèÒª×Ô¼º²¹ÉÏ£¬»òÕßÏȰ´Ã¿´ÎÖ»·¢Ò»Ö¡Ð´ + .clk1(clk), // write clk + .reset(reset), + .WR(WR_mem), //WR_r + .RD(WR_c), + .ADDR_WR(WADDR_r), + .ADDR_RD(RADDR_r), + .DIN(DIN_r), + .cmd_s(cmd_sr), + .chirpID(chirpID), + .Nlen(Nlen), + + .DVALID(DVALID), + .DOUT(DOUT), + .ValidRange(ValidRange), + .data_spi_32(data_spi_32) + ); + +wire [7 : 0] spi_master_byte; +wire spi_master_valid; +//wire miso; +spi_master spi_master_u( + // control signal + .clk(clk), + .reset(reset), + + //// TX(MOSI) signal + .Rx_ready(~ValidRange), // ÐèÒª¶ÁдspiʱÖÃ1 + .axi_byte(DOUT), + .axi_valid(DVALID), + + .ss(ss), // ƬѡÐźŠ+ .spi_master_bit(spi_master_bit), + .spi_clk(spi_clk), + + // RX(MISO) signal + .spi_slave_bit(spi_slave_bit), + .spi_master_byte(spi_master_byte), + .spi_master_valid(spi_master_valid) + + // SPI Interface + + ); + +spi_master_mem spi_master_mem_u( // ¼ÓÒ»¸öreadyÐźţ¬±íʾ¿ÉÒÔ¶Áд£¨spi´«Êýʱ²»ÄܶÁд£© + .clk(clk), + .reset(reset), + .RD(WR_c), // axi + .ADDR_RD(RADDR_r), // axi + .DIN(spi_master_byte), // spi + .DVALID(spi_master_valid), // spi + .cmd_s(cmd_s), + .chirpID(chirpID), + .Nlen(Nlen), + .data_spi_32(data_spi_32), + + .DREADY(~ss), + + .DOUT(RDATA), + .DVALID_o(RVALID) + ); + +reg ss_r1; +reg ss_r2; +always@(negedge clk) +begin + if(reset) + begin + ss_r1 <= 1'b0; + ss_r2 <= 1'b0; + end + else + begin + ss_r1 <= ss; + ss_r2 <= ss_r1; + end +end + +assign WREADY = ss_r2 && ss_r1 && ss; +assign RREADY = ~(ss_r2 && ss_r1 && ss); + +endmodule + diff --git a/spi_tx_rx/spi_master/axi_slave_mem.v b/spi_tx_rx/spi_master/axi_slave_mem.v new file mode 100644 index 0000000..46161da --- /dev/null +++ b/spi_tx_rx/spi_master/axi_slave_mem.v @@ -0,0 +1,371 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2024/03/25 16:00:22 +// Design Name: +// Module Name: axi_slave_mem +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module axi_slave_mem( + clk1, // write clk +// clk2, // read clk + reset, + WR, + RD, + ADDR_WR, + ADDR_RD, + DIN, + cmd_s, + chirpID, + Nlen, // ÿһ֡Êý¾ÝµÄ³¤¶È + + DVALID, + DOUT, + ValidRange, + data_spi_32 +); + +parameter MEM_WORDS = 10000; + +input clk1; +input reset; +input WR; +input RD; +input [31:0] ADDR_WR; +input [31:0] ADDR_RD; +input [31:0] DIN; +input cmd_s; +input [4 :0] chirpID; +input [31:0] Nlen; + +output DVALID; +output [7:0] DOUT; +output ValidRange; +output [31 : 0] data_spi_32; + +reg [32-1:0] Mem_data [MEM_WORDS-1:0]; +reg [32-1:0] Mem_addr [MEM_WORDS-1:0]; +reg WR_r; +wire WR_begin; +wire WR_end; +reg [32-1:0] addr_cnt; +reg [32-1:0] DIN_r; +reg [32-1:0] ADDR_WR_r; + + +always @(posedge clk1) +begin + if (reset) + begin + WR_r <= 1'b0; + DIN_r <= 1'b0; + ADDR_WR_r <= 1'b0; + end + else if(RD == 1'b0) // write + begin + WR_r <= WR; + DIN_r <= DIN; // when need to write, just write the data_in in to memory + ADDR_WR_r <= ADDR_WR; + end + else // read + begin + WR_r <= WR; + DIN_r <= DIN; // when need to write, just write the data_in in to memory + ADDR_WR_r <= ADDR_RD; + end +end +assign WR_begin = WR & (~WR_r); +assign WR_end = (~WR) & (WR_r); + +always @(posedge clk1) +begin + if (WR_begin) + begin + addr_cnt <= 32'b0; + end + else if(WR_r) // ´æ´¢Êý¾ÝºÍµØÖ· + begin + addr_cnt <= addr_cnt + 1'b1; + Mem_data[addr_cnt] <= DIN_r; // when need to write, just write the data_in in to memory + Mem_addr[addr_cnt] <= ADDR_WR_r; + end +end + +wire [31 : 0] Length; //È·¶¨Ö¡³¤¶È +//assign Length = (cmd_s == 1'b0) ? 5'd2 : 5'd17; +assign Length = Nlen + 1'b1; + +reg [6 : 0] data32_cnt; // 32bit data counter [5 : 0]--> 2·ÖƵ£»[6 : 0]--> 4·ÖƵ +reg [31 : 0] length_cnt; // 32bit data counter + +always@(posedge clk1) +begin + if(reset || WR_end) + begin + data32_cnt <= 5'b0; + end + else if(length_cnt == Length) + begin + data32_cnt <= 5'b0; + end + else + begin + data32_cnt <= data32_cnt + 1'b1; + end +end +always@(posedge clk1) +begin + if(reset || WR_end) + begin + length_cnt <= 32'b0; + end + else if(data32_cnt == 7'd127) // 63--> 2·ÖƵ£»127--> 4·ÖƵ + begin + length_cnt <= length_cnt + 1'b1; + end + else if((length_cnt == Length) && (data32_cnt == 5'd0)) + begin + length_cnt <= 32'b0; + end +end +reg [31 : 0] length_cnt_r; +always@(posedge clk1) +begin + if(reset || WR_end) + begin + length_cnt_r <= 32'b0; + end + else + begin + length_cnt_r <= length_cnt; + end + +end + +reg valid_32; // ÿ32bit¶ÔÓ¦Ò»¸övalid +reg valid_32r; +always@(posedge clk1) +begin + if(reset || WR_end || (length_cnt == Length)) + begin + valid_32 <= 1'b0; + valid_32r <= 1'b0; + end + else if(data32_cnt == 5'd1) + begin + valid_32 <= 1'b1; + valid_32r <= valid_32; + end + else + begin + valid_32 <= 1'b0; + valid_32r <= valid_32; + end +end + +reg [31 : 0] data_spi_32; +reg [31 : 0] data_addr_cnt; +reg [31 : 0] data_addr; +reg [31 : 0] data_mem; + +always@(posedge clk1) +begin + if(reset || WR_end || WR_begin) + begin + data_addr_cnt <= 32'b0; + data_spi_32 <= 32'b0; + data_addr <= 32'b0; + data_mem <= 32'b0; + end + else if(RD == 1'b0) + begin + if (data_addr_cnt <= addr_cnt) + begin + if((data32_cnt == 5'd0) && (length_cnt != 1'b1) && (length_cnt != Length)) + begin + data_addr_cnt <= data_addr_cnt + 32'b1; + data_addr <= Mem_addr[data_addr_cnt]; + data_mem <= Mem_data[data_addr_cnt]; + end + if((data32_cnt == 5'd1) && (length_cnt == 1'b0)) // zhentou + begin +// data_spi_32 <= {1'b0, cmd_s,data_addr[24 : 0], 5'b0 }; + data_spi_32 <= {1'b0,data_addr[24 : 0], chirpID, 1'b0 }; + end + else if((data32_cnt == 5'd1)) // && (length_cnt == Length - 1) + begin + data_spi_32 <= data_mem; + end + end + else + begin + data_addr <= 32'hffff; + data_spi_32 <= 32'hffff; + end + end + else if(RD == 1'b1) + begin + if (data_addr_cnt <= addr_cnt) + begin + if((data32_cnt == 5'd0) && (length_cnt != 1'b1) && (length_cnt != Length)) + begin + data_addr_cnt <= data_addr_cnt + 32'b1; + data_addr <= Mem_addr[data_addr_cnt]; + end + if((data32_cnt == 5'd1) && (length_cnt == 1'b0)) // zhentou + begin +// data_spi_32 <= {1'b1, cmd_s,data_addr[24 : 0], 5'b0 }; + data_spi_32 <= {1'b1,data_addr[24 : 0], chirpID, 1'b0 }; + end + else if((data32_cnt == 5'd1)) // && (length_cnt == Length - 1) + begin + data_spi_32 <= 32'b0; + end + end + else + begin + data_addr <= 32'hffff; + data_spi_32 <= 32'hffff; + end + end +end + +reg ss_wr; +always@(posedge clk1) +begin + if(reset || WR_begin || (data_addr_cnt > addr_cnt)) // ÔÚдʱ²»ÔÊÐí´«Êý + begin + ss_wr <= 1'b1; + end + else if ((WR_end)) + begin + ss_wr <= 1'b0; + end +end +reg ss_dr; +always@(posedge clk1) +begin + if(length_cnt_r == Length) // ÿ´«ÍêÒ»Ö¡£¬ssÀ­µÍÒ»¸öclk + begin + ss_dr <= 1'b1; + end + else + begin + ss_dr <= 1'b0; + end +end +reg ss_wr1; +reg ss_wr2; +always@(posedge clk1) +begin + if(reset || (data_addr_cnt > addr_cnt)) + begin + ss_wr1 <= 1'b1; + ss_wr2 <= 1'b1; + end + else + begin + ss_wr1 <= ss_wr; + ss_wr2 <= ss_wr1; + end +end +wire ss_r; +assign ss_r = ss_wr || ss_dr; + +wire ValidRange_r; +assign ValidRange_r = ss_wr2 || ss_dr; +reg ss_r1; +reg ss_r2; +always@(posedge clk1) +begin + if(reset) + begin + ss_r1 <= 1'b1; + ss_r2 <= 1'b1; + end + else + begin + ss_r1 <= ValidRange_r; + ss_r2 <= ss_r1; + end +end + +reg [7 : 0] data_spi; // spi data input +reg [6 : 0] data_spi_cnt; // [5 : 0]->2, [6 : 0] ->4 + +always @(posedge clk1) +if (ValidRange_r | reset) +begin + data_spi_cnt <= 5'b0; +end +else +begin + data_spi_cnt <= data_spi_cnt + 1'b1; +end + +reg valid_spi; +always @(posedge clk1) +if (reset) +begin + data_spi <= 8'b0; + // data_spi_cnt <= 4'b0; //mutl_driven + // data_addr_cnt <= 32'b0; + valid_spi <= 1'b0; +end +else if (~ValidRange_r) +begin + if(data_spi_cnt == 4'b1) + begin + valid_spi <= 1'b1; + data_spi <= data_spi_32[31 : 24]; // ´Ó¸ßµ½µÍ·¢ËÍ + end + else if(data_spi_cnt == 7'd33) + begin + valid_spi <= 1'b1; + data_spi <= data_spi_32[23 : 16]; + end + else if(data_spi_cnt == 7'd65) + begin + valid_spi <= 1'b1; + data_spi <= data_spi_32[15 : 8]; + end + else if(data_spi_cnt == 7'd97) + begin + valid_spi <= 1'b1; + data_spi <= data_spi_32[7 : 0]; + end + else + begin + valid_spi <= 1'b0; + end + +end +else +begin + valid_spi <= 1'b0; +end +wire valid_spi_o; +assign valid_spi_o = valid_spi && (~ss_r); + + +assign DVALID = valid_spi_o; +assign DOUT = data_spi ; +assign ValidRange = ss_r2; + + +endmodule + diff --git a/spi_tx_rx/spi_master/spi_master.v b/spi_tx_rx/spi_master/spi_master.v new file mode 100644 index 0000000..f1c867e --- /dev/null +++ b/spi_tx_rx/spi_master/spi_master.v @@ -0,0 +1,213 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2024/06/24 +// Design Name: +// Module Name: spi_master +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: V0.2 Corresponding to the code of June 19, the spi slave side of the three-state port output +// Fixed a bug where high resistance z was sampled during the first falling edge sampling +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module spi_master + #(parameter SPI_MODE = 3) + ( + // control signal + input clk, + input reset, + + //// TX(MOSI) signal + input Rx_ready, // ÐèÒª¶ÁдspiʱÖÃ1 + input [7 : 0] axi_byte, + input axi_valid, + + output ss, // ƬѡÐźŠ+ output spi_master_bit, + output spi_clk, + + // RX(MISO) signal +// output [7 : 0] RX_byte, +// output RX_valid, + input spi_slave_bit, + output [7 : 0] spi_master_byte, + output spi_master_valid + + // SPI Interface + + ); +wire w_CPOL; // Clock polarity +wire w_CPHA; // Clock phase + +assign w_CPOL = (SPI_MODE == 2) | (SPI_MODE == 3); +assign w_CPHA = (SPI_MODE == 1) | (SPI_MODE == 3); + +reg Rx_ready_r1; +reg Rx_ready_r2; +always@(posedge clk) +begin + if(reset) + begin + Rx_ready_r1 <= 1'b0; + Rx_ready_r2 <= 1'b0; + end + else + begin + Rx_ready_r1 <= Rx_ready; + Rx_ready_r2 <= Rx_ready_r1; + end +end + +reg spi_clk_r; +reg spi_clk_rr; +always@(posedge clk) +begin + if(reset) + begin + spi_clk_r <= 1'b1; + //spi_clk_rr <= 1'b1; + end + else + begin + if(Rx_ready) + begin + spi_clk_r <= spi_clk_r + 1'b1; + end + + //spi_clk_rr <= spi_clk_r; // 2·ÖƵ + end +end +always@(posedge clk) +begin + if(reset) + begin + spi_clk_rr <= 1'b1; + end + else + begin + if(spi_clk_r == 1'b0) + spi_clk_rr <= ~spi_clk_rr; //4·ÖƵ + end +end +reg ss_r; +reg ss_rr; +wire rx_edge; +always@(negedge clk) // only ss need to read negedge of clk +begin + if(reset) + begin + ss_r <= 1'b1; + ss_rr <= ss_r; + // rx_edge_r <= 1'b0; + end + else + begin + ss_r <= ~Rx_ready; + ss_rr <= ss_r; + // rx_edge_r <= rx_edge; + end +end + +wire tx_edge; +assign rx_edge = (spi_clk_r) & (~spi_clk_rr); // mode 3 +assign tx_edge = (~spi_clk_r) & (spi_clk_rr); + +reg rx_edge_r; +reg rx_edge_r2; +reg rx_edge_r3; +always@(posedge clk) +begin + if(reset) + begin + rx_edge_r <= 1'b0; + rx_edge_r2 <= 1'b0; + rx_edge_r3 <= 1'b0; + end + else + begin + rx_edge_r <= rx_edge; + rx_edge_r2 <= rx_edge_r; + rx_edge_r3 <= rx_edge_r2; + end +end + +reg spi_master_bit_r; +//reg spi_master_bit_rr; +reg [7 : 0] spi_master_byte_r; +reg [2 : 0] bit_cnt1; // 0~7 +reg [2 : 0] bit_cnt2; // 0~7 +always@(posedge clk) +begin +// if(reset || (~Rx_ready)) +// begin +// spi_master_bit_r <= 1'b0; +// spi_master_bit_rr <= 1'b0; +// spi_master_byte_r <= 8'b0; +// bit_cnt1 <= 3'd7; +// bit_cnt2 <= 3'd7; +// end + if(reset) + begin + spi_master_bit_r <= 1'b0; + //spi_master_bit_rr <= 1'b0; + spi_master_byte_r <= 8'b0; + bit_cnt1 <= 3'd7; + bit_cnt2 <= 3'd7; + end + else if (~Rx_ready_r1) + begin + bit_cnt1 <= 3'd7; + bit_cnt2 <= 3'd7; + end + else + begin + if(tx_edge) + begin + spi_master_bit_r <= axi_byte[bit_cnt1]; // spi_master_bit_r Ó¦¸Ã°´spi clk ¶ø²»ÊÇ clk ±ä»¯ + bit_cnt1 <= bit_cnt1 - 1'b1; + //spi_master_bit_rr <= spi_master_bit_r; + end + else if(rx_edge_r2) + begin + spi_master_byte_r[bit_cnt2] <= spi_slave_bit; + bit_cnt2 <= bit_cnt2 - 1'b1; + end + end +end + +assign spi_clk = spi_clk_rr; +assign ss = ss_rr; +assign spi_master_bit = spi_master_bit_r; + + + +assign spi_master_byte = spi_master_byte_r; +assign spi_master_valid = ((bit_cnt2 == 3'd7) && (rx_edge_r3 == 1'b1)) ? 1'b1 : 1'b0; + + +/* +reg spi_master_valid_reg; +always@(posedge clk) +begin + if(reset)begin + spi_master_valid_reg <= 1'b0; + end else if(spi_master_valid & Rx_ready)begin + spi_master_valid_reg <= 1'b1; + end else if(~Rx_ready)begin + spi_master_valid_reg <= 1'b0; + end +end +assign miso_valid = spi_master_valid & spi_master_valid_reg; +*/ +endmodule + diff --git a/spi_tx_rx/spi_master/spi_master_mem.v b/spi_tx_rx/spi_master/spi_master_mem.v new file mode 100644 index 0000000..a423f3f --- /dev/null +++ b/spi_tx_rx/spi_master/spi_master_mem.v @@ -0,0 +1,221 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2024/03/26 15:21:07 +// Design Name: +// Module Name: spi_master_mem +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module spi_master_mem( + clk, + reset, + RD, // axi + ADDR_RD, // axi + DIN, // spi + DVALID, // spi + cmd_s, + chirpID, + Nlen, + data_spi_32, + + DREADY, + + DOUT, + DVALID_o +); + +parameter MEM_WORDS = 1000; + +input clk; +input reset; +input RD; +input [31:0] ADDR_RD; +input [7:0] DIN; +input DVALID; +input cmd_s; // Ö¡¸ñʽ¿ØÖÆ×Ö +input [4 :0] chirpID; +input [31:0] Nlen; +input [31 :0] data_spi_32; // ×ÖÍ· + +input DREADY; + +output [31:0] DOUT; +output DVALID_o; + + +reg DREADY_r; +always @(posedge clk) +begin + if(reset) + DREADY_r <= 1'b0; + else + DREADY_r <= DREADY; +end + +reg [1 : 0] valid_cnt; // valid count,ÒÔ4ΪÖÜÆÚ +reg [5 : 0] valid_cnt16; // valid count, ÒÔ16*4ΪÖÜÆÚ +reg [31 : 0] head_cnt; // Ö¡¼ÆÊý +wire [31 : 0] Length; // Ö¡³¤¶È +//assign Length = (cmd_s == 1'b0) ? 8'd7 : 8'd67; // 7 = 2*4 -1; 67 = 17 * 4 -1 +assign Length = (Nlen + 1) * 4 - 1; +reg [31 : 0] data_32; +always @(posedge clk) +begin + if (reset || (~RD) || (~DREADY_r)) + begin + valid_cnt <= 2'b0; + valid_cnt16 <= 4'b0; + data_32 <= 32'b0; + end + else if(RD && DREADY_r && DVALID) + begin + begin + valid_cnt <= valid_cnt + 1'b1; + valid_cnt16 <= valid_cnt16 + 1'b1; + end + + if(valid_cnt == 2'b0) + begin + data_32 <= {DIN, data_32[23 : 0]}; // MSB + end + else if(valid_cnt == 2'd1) + begin + data_32 <= {data_32[31 : 24], DIN, data_32[15 : 0]}; + end + else if(valid_cnt == 2'd2) + begin + data_32 <= {data_32[31 : 16], DIN, data_32[7 : 0]}; + end + else if(valid_cnt == 2'd3) + begin + data_32 <= {data_32[31 : 8], DIN}; + end + end +end + +always @(posedge clk) +begin + if (reset || (~RD) || (~DREADY_r)) + begin + head_cnt <= 32'b0; + end + else if(RD && DREADY_r && DVALID) + begin + if(head_cnt < Length) + begin + head_cnt <= head_cnt + 1'b1; + end + else + begin + head_cnt <= 32'b0; + end + + end +end + +reg DVALID_r; +always@(posedge clk) +begin + if(reset) + begin + DVALID_r <= 1'b0; + end + else + begin + DVALID_r <= DVALID; + end +end + +reg [31 : 0] data_o; +reg valid_o; +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ÓÉÓÚspi masterÄ£¿éµÄ´¦Àí£¬ÕâÀïµÄÊý¾Ý±Èaxi_slave_mem ·¢³öµÄÊý¾ÝÒªÍíһЩ£¬ÐèÒªÑÓʱÒÔ¶ÔÆë +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +reg [31 : 0] data_spi_32_r1; +reg [31 : 0] data_spi_32_r2; +reg [31 : 0] data_spi_32_r3; +reg [31 : 0] data_spi_32_r4; +reg [31 : 0] data_spi_32_r5; +reg [31 : 0] data_spi_32_r6; +reg [31 : 0] data_spi_32_r7; +reg [31 : 0] data_spi_32_r8; +always@(posedge clk) +begin + if(reset) + begin + data_spi_32_r1 <= 32'b0; + data_spi_32_r2 <= 32'b0; + data_spi_32_r3 <= 32'b0; + data_spi_32_r4 <= 32'b0; + data_spi_32_r5 <= 32'b0; + data_spi_32_r6 <= 32'b0; + data_spi_32_r7 <= 32'b0; + data_spi_32_r8 <= 32'b0; + end + else + begin + data_spi_32_r1 <= data_spi_32; + data_spi_32_r2 <= data_spi_32_r1; + data_spi_32_r3 <= data_spi_32_r2; + data_spi_32_r4 <= data_spi_32_r3; + data_spi_32_r5 <= data_spi_32_r4; + data_spi_32_r6 <= data_spi_32_r5; + data_spi_32_r7 <= data_spi_32_r6; + data_spi_32_r8 <= data_spi_32_r7; + end +end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// spi slave ·µ»ØÊý¾ÝÔÚÖ¡Í·´¦·µ»ØÈ«Á㣬²»ÐèÑÓºóÊý¾Ý£¬ÔÚÈ«Áã´¦²ðÈëÖ¡Í·¼´¿É +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +always@(posedge clk) +begin +if(reset || (~RD) || (~DREADY_r)) +begin + data_o <= 32'b0; + valid_o <= 1'b0; +end +begin + if(DVALID_r && (valid_cnt == 2'd0) && (RD) ) //&& DREADY + begin + if(head_cnt == 32'd4) // ÿ֡ǰ4¸ö×Ö½ÚÊÇÖ¡Í· + begin + data_o <= data_spi_32_r8; + valid_o <= 1'b1; + end + else + begin + data_o <= data_32; + valid_o <= 1'b1; + end + end + else + begin + valid_o <= 1'b0; + end +end + +end + + + +assign DOUT = data_o; +assign DVALID_o = valid_o; + + +endmodule + diff --git a/spi_tx_rx/spram_model_0.v b/spi_tx_rx/spram_model_0.v new file mode 100644 index 0000000..f9b5f59 --- /dev/null +++ b/spi_tx_rx/spram_model_0.v @@ -0,0 +1,69 @@ +module spram_model #( + parameter width = 32 + ,parameter depth = 256 +)( + clka, + ena, + dina, + addra, + + clkb, + enb, + doutb, + addrb +); + +//================================================= +function integer clog2(input integer depth); +begin + for(clog2=0;depth>0;clog2=clog2+1) + depth =depth>>1; +end +endfunction +//================================================= + +localparam aw = clog2(depth-1); +//================================================= +input clka; +input ena; +input [width-1:0] dina; +input [aw-1:0] addra; + +input clkb; +input enb; +output [width-1:0] doutb; +input [aw-1:0] addrb; + + +//================================================ +wire clka; +wire ena; +wire [width-1:0] dina; +wire [aw-1:0] addra; + +wire clkb; +wire enb; +reg [width-1:0] doutb; +wire [aw-1:0] addrb; + + +//================================================ +reg [width-1:0] mem[0:depth-1]; + +always@(posedge clka)begin + if(!ena)begin + mem[addra] <=dina; + end +end + +always@(posedge clkb)begin + if(!enb)begin + doutb <=mem[addrb]; + end + else begin + doutb <=0; + end +end + +endmodule + diff --git a/spi_tx_rx/top/sram_z_top.v b/spi_tx_rx/top/sram_z_top.v new file mode 100644 index 0000000..83af589 --- /dev/null +++ b/spi_tx_rx/top/sram_z_top.v @@ -0,0 +1,502 @@ +//+FHDR-------------------------------------------------------------------------------------------------------- +// Company: +//----------------------------------------------------------------------------------------------------------------- +// File Name : spi_to_sram_v1.2.v +// Department : +// Author : ZYZ +// Author's Tel : +//----------------------------------------------------------------------------------------------------------------- +// Relese History +// Version Date Author Description +// 0.1 2024-05-30 ZYZ +//----------------------------------------------------------------------------------------------------------------- +// Keywords : (1) connect rx_sram , tx_sram , spi-master ,digital_top successfully,the +// verilog files of the digital_top is marked 2024.5.17 +// (2) when reading data,tx_sram still need to complete the data +// +//----------------------------------------------------------------------------------------------------------------- +// Parameter +// +//----------------------------------------------------------------------------------------------------------------- +// Purpose : +// +//----------------------------------------------------------------------------------------------------------------- +// Target Device: +// Tool versions: +//----------------------------------------------------------------------------------------------------------------- +// Reuse Issues +// Reset Strategy: +// Clock Domains: +// Critical Timing: +// Asynchronous I/F: +// Synthesizable (y/n): +// Other: +//-FHDR-------------------------------------------------------------------------------------------------------- + +`include "../../rtl/define/chip_define.v" + +module sram_z_top( + input clk + ,input por_rstn + + ,input async_rstn // hardware Reset, active low + //sync + ,input sync_in // Chip synchronization signal input, high pulse valid + ,output sync_out // Chip synchronization signal output, high pulse valid + + ,input [1 :0] ch0_feedback // Ch0 Feedback signals from the readout chip + `ifdef CHANNEL_IS_FOUR + ,input [1 :0] ch1_feedback // Ch1 Feedback signals from the readout chip + ,input [1 :0] ch2_feedback // Ch2 Feedback signals from the readout chip + ,input [1 :0] ch3_feedback // Ch3 Feedback signals from the readout chip + `endif + ,input [4 :0] cfgid // During power-on initialization, the IO configuration + // values are read as the chip ID number + //irq + ,output irq + ,output [5 :0] PO_ch0_att // CH0 Attenuator Control Bit + //tx_sram port + ,input [31 :0] din + ,input [15 :0] data_length + ,output data_done_all + ,output data_out_per + + //digital_top port + ,output oen + //rx_sram port + ,input data_rden_rx + ,output [31:0] Rdata_PC + // PLL LOCK + //------------------------------Ch0 DAC cfg pin---------------------------------------------------- + ,output [2 :0] ch0_dac_addr + ,output [2 :0] ch0_dac_dw + ,output [8 :0] ch0_dac_ref + ,output [16 :0] ch0_dac_Prbs_rst0 + ,output [16 :0] ch0_dac_Prbs_set0 + ,output [16 :0] ch0_dac_Prbs_rst1 + ,output [16 :0] ch0_dac_Prbs_set1 + ,output ch0_dac_Cal_sig + ,output ch0_dac_Cal_rstn + ,output ch0_dac_Cal_div_rstn + ,input ch0_dac_Cal_end + ,output [2 :0] ch0_dac_Ctrlp + ,output [2 :0] ch0_dac_Ctrln + //------------------------------Ch0 DC Bias cfg pin---------------------------------------------------- + ,output [2 :0] ch0_dc_addr + ,output [2 :0] ch0_dc_dw + ,output [8 :0] ch0_dc_ref + ,output ch0_dc_Cal_sig + ,output ch0_dc_Cal_rstn + ,output ch0_dc_Cal_div_rstn + ,input ch0_dc_Cal_end + //------------------------------Ch0 DSP data out---------------------------------------------------- + ,output [15 :0] ch0_z_dsp_dout0 + ,output [15 :0] ch0_z_dsp_dout1 + ,output [15 :0] ch0_z_dsp_dout2 + ,output [15 :0] ch0_z_dsp_dout3 + ,output [15 :0] ch0_dc_bias_o + ,output ch0_dc_bias_latch +); + +//tx_sram signal +wire [31:0] Nlen; +wire [4 :0] chip_ID; +wire [24:0] address; +wire [31:0] data_out_rx; +wire wr_en; +wire rd_en; +wire RREADY; +wire WREADY; +//axi-spi signal +wire spi_master_bit; +wire spi_clk; +wire ss; +wire spi_slave_bit; +//rx_sram signal +wire [31:0] RDATA; +wire RVALID; + +wire [14 :0] ch0_z_DEM_MSB_OUT0; +wire [14 :0] ch0_z_DEM_MSB_OUT1; +wire [14 :0] ch0_z_DEM_MSB_OUT2; +wire [14 :0] ch0_z_DEM_MSB_OUT3; +wire [6 :0] ch0_z_DEM_ISB_OUT0; +wire [6 :0] ch0_z_DEM_ISB_OUT1; +wire [6 :0] ch0_z_DEM_ISB_OUT2; +wire [6 :0] ch0_z_DEM_ISB_OUT3; +wire [8 :0] ch0_z_DEM_LSB_OUT0; +wire [8 :0] ch0_z_DEM_LSB_OUT1; +wire [8 :0] ch0_z_DEM_LSB_OUT2; +wire [8 :0] ch0_z_DEM_LSB_OUT3; + +tx_sram inst_tx_sram( + .clk(clk), + .rstn(por_rstn), + //input + .dina(din), + .data_length (data_length), + + .WREADY (WREADY), + .RREADY (RREADY), + //output + .Nlen (Nlen), + .chip_ID (chip_ID), + .address (address), + .data_out (data_out_rx), + .wr_en (wr_en), + .rd_en (rd_en), + + .data_done_all (data_done_all), + .data_out_per (data_out_per) +); + + +AxiSpi inst_AxiSpi( + .clk (clk ), + .reset (!por_rstn ), + .WR (wr_en ), + .RD (rd_en ), + //input + .WADDR ({7'b0,address}), + .RADDR ({7'b0,address}), + .DIN (data_out_rx ), + .WVALID ( ), + .cmd_s ( ), + .chirpID (chip_ID ), + .Nlen (Nlen ), + //output + .WREADY (WREADY ), + .RREADY (RREADY ), + // read data from spi slave, need to send to axi + .RVALID (RVALID ), + .RDATA (RDATA ), + + // interface to spi slave + .spi_slave_bit (spi_slave_bit ), //miso + + .ss (ss ), //ss + .spi_clk (spi_clk ), //2 or 4 + .spi_master_bit (spi_master_bit) //mosi + ); + + +rx_sram inst_rx_sram( + .clk (clk), + .rstn (por_rstn), + + .din (RDATA), + .din_vld (RVALID), + + .data_rden_rx (data_rden_rx), + .Rdata_PC (Rdata_PC) +); + + +z_chip_top inst_chip_top ( + //+++++++++++++++++++++++++++++++++++++++++++++// + // PAD Strat // + //+++++++++++++++++++++++++++++++++++++++++++++// + .PI_async_rstn (async_rstn )// hardware Reset, active low + //sync + ,.PI_sync_in (sync_in ) // Chip synchronization signal input, high pulse valid + ,.PO_sync_out (sync_out ) // Chip synchronization signal output, high pulse valid + //Feedback signal + ,.PI_ch0_feedback (ch0_feedback)// Ch0 Feedback signals from the readout chip + `ifdef CHANNEL_IS_FOUR + ,.PI_ch1_feedback (ch1_feedback) // Ch1 Feedback signals from the readout chip + ,.PI_ch2_feedback (ch2_feedback) // Ch2 Feedback signals from the readout chip + ,.PI_ch3_feedback (ch3_feedback) // Ch3 Feedback signals from the readout chip + `endif + //config chip id + ,.PI_cfgid (cfgid)// During power-on initialization, the IO configuration + // values are read as the chip ID number + //spi port + ,.PI_sclk (spi_clk ) // Spi Clock + ,.PI_csn (ss ) // Spi Chip Select active low + ,.PI_mosi (spi_master_bit) // Spi Mosi + ,.PO_miso (spi_slave_bit ) // Spi Miso + //irq + ,.PO_irq (irq )// Interrupt signal in the chip, high level active + //Attenuator Control Bit\u200c + ,.PO_ch0_att (PO_ch0_att ) // CH0 Attenuator Control Bit + `ifdef CHANNEL_IS_FOUR + ,.PO_ch1_att ( ) // CH1 Attenuator Control Bit + ,.PO_ch2_att ( ) // CH2 Attenuator Control Bit + ,.PO_ch3_att ( ) // CH3 Attenuator Control Bit + `endif + //+++++++++++++++++++++++++++++++++++++++++++++// + // PAD End // + //+++++++++++++++++++++++++++++++++++++++++++++// + //+++++++++++++++++++++++++++++++++++++++++++++// + // PIN Strat // + //+++++++++++++++++++++++++++++++++++++++++++++// + //-------------------------clcok pin from pll------------------------------------------------- + ,.clk (clk )// System Main Clock + //-------------------------Power on reset pin from por---------------------------------------- + ,.por_rstn (por_rstn )// Power on reset, active low + //------------------------------digital IO---------------------------------------------------- + //------------------------------PLL cfg pin---------------------------------------------------- + ,.ref_sel ( )// Clock source selection for a frequency divider; + // 1'b0:External clock source + // 1'b1:internal phase-locked loop clock source + ,.ref_en ( )// Input reference clock enable + // 1'b0:enable,1'b1:disable + ,.ref_s2d_en ( )// Referenced clock differential to single-ended conversion enable + // 1'b0:enable,1'b1:disable + ,.p_cnt ( ) // P counter + ,.pfd_delay ( ) // PFD Dead Zone + ,.pfd_dff_Set ( ) // Setting the PFD register,active high + ,.pfd_dff_4and ( ) // PFD output polarity + ,.spd_div ( ) // SPD Frequency Divider + ,.spd_pulse_width ( ) // Pulse Width of SPD + ,.spd_pulse_sw ( ) // Pulse sw of SPD + ,.cpc_sel ( ) // current source selection + ,.swcp_i ( ) // PTAT current switch + ,.sw_ptat_r ( ) // PTAT current adjustment + //,output [1 :0] sw_fll_cpi // Phase-locked loop charge pump current + //,output sw_fll_delay // PLL Dead Zone + ,.pfd_sel ( ) // PFD Loop selection + ,.spd_sel ( ) // SPD Loop selection + ,.dtd_en ( ) // + //,output fll_sel // FLL Loop selection + ,.vco_tc ( ) // VCO temperature compensation + ,.vco_tcr ( ) // VCO temperature compensation resistor + ,.vco_gain_adj ( ) // VCO gain adjustment + ,.vco_gain_adj_r ( ) // VCO gain adjustment resistor + ,.vco_cur_adj ( ) // VCO current adjustment + ,.vco_buff_en ( ) // VCO buff enable,active high + ,.vco_en ( ) // VCO enable,active high + ,.vco_fb_adj ( ) // VCO frequency band adjustment +// ,.pll_dpwr_adj ( ) // PLL frequency division output power adjustment +// ,output [7 :0] vco_fb_adj // VCO frequency band adjustment + ,.tc_sel ( ) // Temperature compensation options + ,.pata_res_en ( ) // PATAMOS resistance enable + ,.pata_s_dc_sel ( ) // PATA slope DC selection + ,.pata_res_vdc300 ( ) // PATAMOS resistance bias + ,.pata_res_vdc500 ( ) // PATAMOS resistance bias + ,.pata_res_vdc800 ( ) // PATAMOS resistance bias + ,.sw_var_temp_en ( ) // Temperature-compensated automatic switch + ,.sw_var_temp ( ) // Temperature-compensated manual switch + + ,.afc_en ( ) // AFC enable + ,.afc_shutdown ( ) // AFC module shutdown signal + ,.afc_reset ( ) // AFC reset + //,output [0 :0] afc_det_speed // AFC detection speed + //,output [0 :0] flag_out_sel // Read and choose the signs + ,.afc_clk_sel ( ) // AFC clock frequency choose + ,.afc_pres ( ) // AFC comparator accuracy adjustment + + ,.afc_fb_cnt ( ) // AFC frequency band adjustment function counter + ,.afc_fb_target ( ) // AFC frequency band adjustment function target number of cycles + + ,.afc_ld_cnt ( ) // Adjust the counting time of the AFC lock detection // feature counter + ,.afc_ld_target ( )// AFC Lock Detection Function Target Cycle Count + + ,.div_rstn_sel ( ) // div rstn select, 1'b0: ext clear, 1'b1:inter pll lock + ,.test_clk_sel ( ) // test clk select, 4'b0001:DIV1 clk, 4'b0010:DIV2 clk, 4'b0100:DIV4 clk, 4'b1000:DIV8 clk + ,.test_clk_oen ( ) // test clk output enable, 1'b0:disenable, 1'b1:enable + ,.dig_clk_sel ( ) // digital main clk select, one hot code,bit[0]-->0 degree phase,bit[1]-->45 degree phase.....bit[7]-->315degree phae + ,.clkrx_pdn ( ) // CLock Rx Power Down + ,.sync_clr ( ) // PLL div sync clr,low active + ,.pll_rstn ( ) // PLL reset,active low + ,.pll_lock ( ) // PLL LOCK + ,.afc_end_flag ( ) + ,.clk_resv ( ) + //------------------------------Ch0 DAC cfg pin---------------------------------------------------- + ,.ch0_dac_addr (ch0_dac_addr ) + ,.ch0_dac_dw (ch0_dac_dw ) + ,.ch0_dac_ref (ch0_dac_ref ) + ,.ch0_dac_Prbs_rst0 (ch0_dac_Prbs_rst0 ) + ,.ch0_dac_Prbs_set0 (ch0_dac_Prbs_set0 ) + ,.ch0_dac_Prbs_rst1 (ch0_dac_Prbs_rst1 ) + ,.ch0_dac_Prbs_set1 (ch0_dac_Prbs_set1 ) + ,.ch0_dac_Cal_sig (ch0_dac_Cal_sig ) + ,.ch0_dac_Cal_rstn (ch0_dac_Cal_rstn ) + ,.ch0_dac_Cal_div_rstn(ch0_dac_Cal_div_rstn) + ,.ch0_dac_Cal_end (ch0_dac_Cal_end ) + ,.ch0_dac_Ctrlp (ch0_dac_Ctrlp ) + ,.ch0_dac_Ctrln (ch0_dac_Ctrln ) + //------------------------------Ch0 DC Bias cfg pin---------------------------------------------------- + ,.ch0_dc_addr (ch0_dc_addr ) + ,.ch0_dc_dw (ch0_dc_dw ) + ,.ch0_dc_ref (ch0_dc_ref ) + ,.ch0_dc_Cal_sig (ch0_dc_Cal_sig ) + ,.ch0_dc_Cal_rstn (ch0_dc_Cal_rstn ) + ,.ch0_dc_Cal_div_rstn (ch0_dc_Cal_div_rstn) + ,.ch0_dc_Cal_end (ch0_dc_Cal_end ) + `ifdef CHANNEL_IS_FOUR + //------------------------------Ch1 DAC cfg pin---------------------------------------------------- + ,.ch1_dac_addr () + ,.ch1_dac_dw () + ,.ch1_dac_ref () + ,.ch1_dac_Prbs_rst0 () + ,.ch1_dac_Prbs_set0 () + ,.ch1_dac_Prbs_rst1 () + ,.ch1_dac_Prbs_set1 () + ,.ch1_dac_Cal_sig () + ,.ch1_dac_Cal_rstn () + ,.ch1_dac_Cal_div_rstn() + ,.ch1_dac_Cal_end () + ,.ch1_dac_Ctrlp () + ,.ch1_dac_Ctrln () + //------------------------------Ch1 DC Bias cfg pin---------------------------------------------------- + ,.ch1_dc_addr () + ,.ch1_dc_dw () + ,.ch1_dc_ref () + ,.ch1_dc_Cal_sig () + ,.ch1_dc_Cal_rstn () + ,.ch1_dc_Cal_div_rstn () + ,.ch1_dc_Cal_end () + //------------------------------Ch2 DAC cfg pin---------------------------------------------------- + ,.ch2_dac_addr () + ,.ch2_dac_dw () + ,.ch2_dac_ref () + ,.ch2_dac_Prbs_rst0 () + ,.ch2_dac_Prbs_set0 () + ,.ch2_dac_Prbs_rst1 () + ,.ch2_dac_Prbs_set1 () + ,.ch2_dac_Cal_sig () + ,.ch2_dac_Cal_rstn () + ,.ch2_dac_Cal_div_rstn() + ,.ch2_dac_Cal_end () + ,.ch2_dac_Ctrlp () + ,.ch2_dac_Ctrln () + //------------------------------Ch2 DC Bias cfg pin---------------------------------------------------- + ,.ch2_dc_addr () + ,.ch2_dc_dw () + ,.ch2_dc_ref () + ,.ch2_dc_Cal_sig () + ,.ch2_dc_Cal_rstn () + ,.ch2_dc_Cal_div_rstn () + ,.ch2_dc_Cal_end () + //------------------------------Ch3 DAC cfg pin---------------------------------------------------- + ,.ch3_dac_addr () + ,.ch3_dac_dw () + ,.ch3_dac_ref () + ,.ch3_dac_Prbs_rst0 () + ,.ch3_dac_Prbs_set0 () + ,.ch3_dac_Prbs_rst1 () + ,.ch3_dac_Prbs_set1 () + ,.ch3_dac_Cal_sig () + ,.ch3_dac_Cal_rstn () + ,.ch3_dac_Cal_div_rstn() + ,.ch3_dac_Cal_end () + ,.ch3_dac_Ctrlp () + ,.ch3_dac_Ctrln () +//------------------------------Ch3 DC Bias cfg pin---------------------------------------------------- + ,.ch3_dc_addr () + ,.ch3_dc_dw () + ,.ch3_dc_ref () + ,.ch3_dc_Cal_sig () + ,.ch3_dc_Cal_rstn () + ,.ch3_dc_Cal_div_rstn () + ,.ch3_dc_Cal_end () + `endif + `ifdef CHANNEL_Z_ON + //------------------------------Ch0 DSP data out---------------------------------------------------- + ,.ch0_z_DEM_MSB_OUT0 (ch0_z_DEM_MSB_OUT0) + ,.ch0_z_DEM_MSB_OUT1 (ch0_z_DEM_MSB_OUT1) + ,.ch0_z_DEM_MSB_OUT2 (ch0_z_DEM_MSB_OUT2) + ,.ch0_z_DEM_MSB_OUT3 (ch0_z_DEM_MSB_OUT3) + ,.ch0_z_DEM_ISB_OUT0 (ch0_z_DEM_ISB_OUT0) + ,.ch0_z_DEM_ISB_OUT1 (ch0_z_DEM_ISB_OUT1) + ,.ch0_z_DEM_ISB_OUT2 (ch0_z_DEM_ISB_OUT2) + ,.ch0_z_DEM_ISB_OUT3 (ch0_z_DEM_ISB_OUT3) + ,.ch0_z_DEM_LSB_OUT0 (ch0_z_DEM_LSB_OUT0) + ,.ch0_z_DEM_LSB_OUT1 (ch0_z_DEM_LSB_OUT1) + ,.ch0_z_DEM_LSB_OUT2 (ch0_z_DEM_LSB_OUT2) + ,.ch0_z_DEM_LSB_OUT3 (ch0_z_DEM_LSB_OUT3) + ,.ch0_dc_bias_o (ch0_dc_bias_o ) + ,.ch0_dc_bias_latch (ch0_dc_bias_latch ) + `endif + `ifdef CHANNEL_IS_FOUR + //------------------------------Ch1 DSP data out---------------------------------------------------- + `ifdef CHANNEL_Z_ON + ,.ch1_z_DEM_MSB_OUT0 ( ) + ,.ch1_z_DEM_MSB_OUT1 ( ) + ,.ch1_z_DEM_MSB_OUT2 ( ) + ,.ch1_z_DEM_MSB_OUT3 ( ) + ,.ch1_z_DEM_ISB_OUT0 ( ) + ,.ch1_z_DEM_ISB_OUT1 ( ) + ,.ch1_z_DEM_ISB_OUT2 ( ) + ,.ch1_z_DEM_ISB_OUT3 ( ) + ,.ch1_z_DEM_LSB_OUT0 ( ) + ,.ch1_z_DEM_LSB_OUT1 ( ) + ,.ch1_z_DEM_LSB_OUT2 ( ) + ,.ch1_z_DEM_LSB_OUT3 ( ) + ,.ch1_dc_bias_o ( ) + ,.ch1_dc_bias_latch ( ) + `endif + //------------------------------Ch2 DSP data out---------------------------------------------------- + `ifdef CHANNEL_Z_ON + ,.ch2_z_DEM_MSB_OUT0 ( ) + ,.ch2_z_DEM_MSB_OUT1 ( ) + ,.ch2_z_DEM_MSB_OUT2 ( ) + ,.ch2_z_DEM_MSB_OUT3 ( ) + ,.ch2_z_DEM_ISB_OUT0 ( ) + ,.ch2_z_DEM_ISB_OUT1 ( ) + ,.ch2_z_DEM_ISB_OUT2 ( ) + ,.ch2_z_DEM_ISB_OUT3 ( ) + ,.ch2_z_DEM_LSB_OUT0 ( ) + ,.ch2_z_DEM_LSB_OUT1 ( ) + ,.ch2_z_DEM_LSB_OUT2 ( ) + ,.ch2_z_DEM_LSB_OUT3 ( ) + ,.ch2_dc_bias_o ( ) + ,.ch2_dc_bias_latch ( ) + `endif + //------------------------------Ch3 DSP data out---------------------------------------------------- + `ifdef CHANNEL_Z_ON + ,.ch3_z_DEM_MSB_OUT0 ( ) + ,.ch3_z_DEM_MSB_OUT1 ( ) + ,.ch3_z_DEM_MSB_OUT2 ( ) + ,.ch3_z_DEM_MSB_OUT3 ( ) + ,.ch3_z_DEM_ISB_OUT0 ( ) + ,.ch3_z_DEM_ISB_OUT1 ( ) + ,.ch3_z_DEM_ISB_OUT2 ( ) + ,.ch3_z_DEM_ISB_OUT3 ( ) + ,.ch3_z_DEM_LSB_OUT0 ( ) + ,.ch3_z_DEM_LSB_OUT1 ( ) + ,.ch3_z_DEM_LSB_OUT2 ( ) + ,.ch3_z_DEM_LSB_OUT3 ( ) + ,.ch3_dc_bias_o ( ) + ,.ch3_dc_bias_latch ( ) + `endif + `endif + //+++++++++++++++++++++++++++++++++++++++++++++// + // PIN END // + //+++++++++++++++++++++++++++++++++++++++++++++// + + +); + +thermo2binary_top Ch0_0_thermo2binary_top ( + .clk ( clk ) + ,.DEM_MSB_IN ( ch0_z_DEM_MSB_OUT0 ) + ,.DEM_ISB_IN ( ch0_z_DEM_ISB_OUT0 ) + ,.DEM_LSB_IN ( ch0_z_DEM_LSB_OUT0 ) + ,.DOUT ( ch0_z_dsp_dout0 ) +); +thermo2binary_top Ch0_1_thermo2binary_top ( + .clk ( clk ) + ,.DEM_MSB_IN ( ch0_z_DEM_MSB_OUT1 ) + ,.DEM_ISB_IN ( ch0_z_DEM_ISB_OUT1 ) + ,.DEM_LSB_IN ( ch0_z_DEM_LSB_OUT1 ) + ,.DOUT ( ch0_z_dsp_dout1 ) +); +thermo2binary_top Ch0_2_thermo2binary_top ( + .clk ( clk ) + ,.DEM_MSB_IN ( ch0_z_DEM_MSB_OUT2 ) + ,.DEM_ISB_IN ( ch0_z_DEM_ISB_OUT2 ) + ,.DEM_LSB_IN ( ch0_z_DEM_LSB_OUT2 ) + ,.DOUT ( ch0_z_dsp_dout2 ) +); +thermo2binary_top Ch0_3_thermo2binary_top ( + .clk ( clk ) + ,.DEM_MSB_IN ( ch0_z_DEM_MSB_OUT3 ) + ,.DEM_ISB_IN ( ch0_z_DEM_ISB_OUT3 ) + ,.DEM_LSB_IN ( ch0_z_DEM_LSB_OUT3 ) + ,.DOUT ( ch0_z_dsp_dout3 ) +); + + +endmodule diff --git a/spi_tx_rx/tx/tx_sram.v b/spi_tx_rx/tx/tx_sram.v new file mode 100644 index 0000000..b33277a --- /dev/null +++ b/spi_tx_rx/tx/tx_sram.v @@ -0,0 +1,251 @@ +// Relese History +// Version Date Author Description +// 0.3 2024-05-29 ZYZ +//----------------------------------------------------------------------------------------------------------------- +// Keywords : connect spi-master +// +//----------------------------------------------------------------------------------------------------------------- +// Parameter : +// cmd[31:0] form: +// form-v0.2 {WR ,RSV ,ID ,ADDR} +// [31] [30] [29:25] [24:0] +// +// form-v0.3 {WR ,ADDR ,ID ,RSV} +// [31] [30:6] [5:1] [0] +// +// form-v0.2 is defined by design , it has len[31:0]; +// form-v0.3 is produced by spi interface ,it doesn't have len[31:0]; +// +// size : 256K +//----------------------------------------------------------------------------------------------------------------- +// Purpose : +// +//----------------------------------------------------------------------------------------------------------------- +// Target Device: +// Tool versions: +//----------------------------------------------------------------------------------------------------------------- +// Reuse Issues +// Reset Strategy: +// Clock Domains: +// Critical Timing: +// Asynchronous I/F: +// Synthesizable (y/n): +// Other: +//-FHDR-------------------------------------------------------------------------------------------------------- +module tx_sram( + input clk, + input rstn, + + (* mark_debug="true" *)input [31:0] dina, + (* mark_debug="true" *)input [15:0] data_length, + + output [31:0] Nlen, + output [4 :0] chip_ID, + output [24:0] address, + output [31:0] data_out, + (* mark_debug="true" *)output wr_en, + (* mark_debug="true" *)output rd_en, + + (* mark_debug="true" *)input WREADY, + (* mark_debug="true" *)input RREADY, + + output data_done_all, + output data_out_per +); + + +parameter width = 32 ; +parameter depth = 65536 ; + +//================================================= +function integer clog2(input integer depth); +begin + for(clog2=0;depth>0;clog2=clog2+1) + depth =depth>>1; +end +endfunction +//================================================= + +localparam aw = clog2(depth-1); + +//================================================= +//wr&rd address + +(* mark_debug="true" *) reg [aw-1:0]cnta ; +(* mark_debug="true" *) reg [aw-1:0]cntb ; + +(* mark_debug="true" *) wire ena ; +(* mark_debug="true" *) wire enb ; +(* mark_debug="true" *) wire full ; +(* mark_debug="true" *) wire [31:0] doutb; + +//current len of data ,initial value is 0 +(* mark_debug="true" *) reg [31:0]len_current ; + +//cmd +(* mark_debug="true" *) reg cmd_s ; +(* mark_debug="true" *) reg [4:0] chip_ID_reg ; +(* mark_debug="true" *)reg [24:0]address_reg ; +always@(posedge clk or negedge rstn)begin + if(!rstn)begin + cmd_s <= 1'b0; + chip_ID_reg <= 5'b0; + address_reg <= 25'b0; + end + else if(cntb == len_current + 2'd1)begin + cmd_s <= doutb[31]; + chip_ID_reg <= doutb[5:1]; + address_reg <= doutb[30:6]; + end + else begin + cmd_s <= cmd_s; + chip_ID_reg <= chip_ID_reg; + address_reg <= address_reg; + end +end +assign chip_ID = chip_ID_reg; +assign address = address_reg; + + +//len of data_out +(* mark_debug="true" *) reg [31:0]len_reg ; +always@(posedge clk or negedge rstn)begin + if(!rstn)begin + len_reg <= 32'b0; + end + else if(cntb == len_current + 2'd2)begin + len_reg <= doutb ; + end + else begin + len_reg <= len_reg; + end +end +assign Nlen = len_reg; + + +//data_out +(* mark_debug="true" *) reg [31:0]data_out_reg ; +(* mark_debug="true" *) wire data_out_en ; +always@(posedge clk or negedge rstn)begin + if(!rstn)begin + data_out_reg <= 32'b0; + end + else if(data_out_en)begin + data_out_reg <= doutb ; + end + else begin + data_out_reg <= 32'b0; + end +end + +reg data_out_en_r1; +always@(posedge clk or negedge rstn)begin + if(!rstn)begin + data_out_en_r1 <= 1'b0; + end + else begin + data_out_en_r1 <= data_out_en; + end +end + +assign data_out = data_out_reg; +assign data_out_en = (cntb >= len_current + 2'd3) & (cntb <= len_current + len_reg + 2'd2); + +//signal send to spi_master +assign wr_en = !cmd_s & data_out_en_r1; +assign rd_en = cmd_s & data_out_en_r1; + +//signal send to PC +assign data_out_per = (cntb == len_current + 3'd3 ) ? 1'b1 : 1'b0; +assign data_done_all = (cntb == data_length-1'b1 | cnta == data_length - 1'b1) ? 1'b1 : 1'b0; + +//the time ready for writing data and updata len_current +reg [2:0] wready_reg; +always @(posedge clk or negedge rstn) + begin + if(!rstn ) begin + wready_reg <= 3'b0; + end + else begin + wready_reg <= {wready_reg[1:0],WREADY}; + end + end +assign wready_posedge = wready_reg[1:0] == 2'b01 ? 1'b1 : 1'b0; + +//updata len_current and cntb +always@(posedge clk or negedge rstn)begin + if(!rstn)begin + len_current <= 32'b0; + end + else if( wready_posedge & len_reg != 0)begin + len_current <= len_current + len_reg + 2'd2 ; + end + else begin + len_current <= len_current; + end +end + +//write address: addra +//read address: addrb +always @(posedge clk or negedge rstn) + begin + if(!rstn) begin + cnta <= 'hffff; + end + else if(ena) begin + cnta <= cnta + 1'b1; + end + else + cnta <= cnta ; + end + +always @(posedge clk or negedge rstn) + begin + if(!rstn ) begin + cntb <= 'h0 ; + end + else if(enb) begin + cntb <= cntb + 1'b1; + end + else if(wready_posedge & len_reg != 0) begin + cntb <= cntb - 1'b1 ; // better solution? + end + else begin + cntb <= cntb; + end + end + +assign full = (cnta+1'b1 <= data_length )? 1'b0 : 1'b1 ; +assign ena = !full; +assign enb = full & (cntb <= data_length ) & WREADY & (cntb <= len_current + len_reg + 2'd2); +/* +blk_mem_gen_0 blk_mem_gen_0_inst( + .clka(clk), + .ena(1'b1), + .wea(ena), + .dina(dina), + .addra(cnta), + + .clkb(clk), + .enb(enb), + .doutb(doutb), + .addrb(cntb) +); +*/ +spram_model #( + .width(width), + .depth(depth) +)spram_inst( + .clka(clk), + .ena(~ena), + .dina(dina), + .addra(cnta), + + .clkb(clk), + .enb(~enb), + .doutb(doutb), + .addrb(cntb) +); + +endmodule +