`timescale 1ns / 1ns ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2019/11/18 23:18:07 // Design Name: // Module Name: Message_Store // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module Message_Store #( parameter WIDTH = 4'd8 ) ( input clk, input rst_MS, input framesync_MS, //帧同步标志,高脉冲 input nd_MS, //译码输入数据有效标志,高有效 input [WIDTH-1:0] din_MS, //译码输入软信息 input [ 0:0] oe_MS, //使能输出信号,高脉冲 output deal_end_MS, //转换完成标志 output syncout_MS, //高脉冲 output rdy_MS, //高有效的连续信号 output reg [WIDTH-1:0] dout01_MS = 8'd0, // 输出数据 output reg [WIDTH-1:0] dout02_MS = 8'd0, output reg [WIDTH-1:0] dout03_MS = 8'd0, output reg [WIDTH-1:0] dout04_MS = 8'd0 ); reg [10:0] cnt_MS = 11'd0; reg flag_end = 1'd0; always @(posedge clk) begin if (rst_MS) begin flag_end <= 11'd0; end else begin if (framesync_MS) flag_end <= 1'd1; else if (nd_MS && cnt_MS == 11'd2047) flag_end <= 1'd0; else flag_end <= flag_end; end end // 产生基准计数 always @(posedge clk) begin if (rst_MS) begin cnt_MS <= 11'd0; end else begin if (flag_end) begin if (nd_MS) cnt_MS <= cnt_MS + 11'd1; else begin cnt_MS <= cnt_MS; end end else begin cnt_MS <= cnt_MS; end end end reg wea1_01 = 1'd0, wea1_02 = 1'd0, wea1_03 = 1'd0, wea1_04 = 1'd0, wea2_01 = 1'd0, wea2_02 = 1'd0, wea2_03 = 1'd0, wea2_04 = 1'd0; reg [8:0] addr_wr1_01 = 9'd511, addr_wr1_02 = 9'd511, addr_wr1_03 = 9'd511, addr_wr1_04 = 9'd511, addr_wr2_01 = 9'd511, addr_wr2_02 = 9'd511, addr_wr2_03 = 9'd511, addr_wr2_04 = 9'd511; reg [WIDTH-1:0] din1_01 = 8'd0, din1_02 = 8'd0, din1_03 = 8'd0, din1_04 = 8'd0, din2_01 = 8'd0, din2_02 = 8'd0, din2_03 = 8'd0, din2_04 = 8'd0; reg [8:0] addr_rd1_01 = 9'd511, addr_rd1_02 = 9'd511, addr_rd1_03 = 9'd511, addr_rd1_04 = 9'd511, addr_rd2_01 = 9'd511, addr_rd2_02 = 9'd511, addr_rd2_03 = 9'd511, addr_rd2_04 = 9'd511; wire [WIDTH-1:0] dout1_01, dout1_02, dout1_03, dout1_04, dout2_01, dout2_02, dout2_03, dout2_04; RAM_512_8 Lp1_01 ( .clka (clk), .wea (wea1_01), .addra(addr_wr1_01), .dina (din1_01), .clkb (clk), .addrb(addr_rd1_01), .doutb(dout1_01) ); RAM_512_8 Lp1_02 ( .clka (clk), .wea (wea1_02), .addra(addr_wr1_02), .dina (din1_02), .clkb (clk), .addrb(addr_rd1_02), .doutb(dout1_02) ); RAM_512_8 Lp1_03 ( .clka (clk), .wea (wea1_03), .addra(addr_wr1_03), .dina (din1_03), .clkb (clk), .addrb(addr_rd1_03), .doutb(dout1_03) ); RAM_512_8 Lp1_04 ( .clka (clk), .wea (wea1_04), .addra(addr_wr1_04), .dina (din1_04), .clkb (clk), .addrb(addr_rd1_04), .doutb(dout1_04) ); RAM_512_8 Lp2_01 ( .clka (clk), .wea (wea2_01), .addra(addr_wr2_01), .dina (din2_01), .clkb (clk), .addrb(addr_rd2_01), .doutb(dout2_01) ); RAM_512_8 Lp2_02 ( .clka (clk), .wea (wea2_02), .addra(addr_wr2_02), .dina (din2_02), .clkb (clk), .addrb(addr_rd2_02), .doutb(dout2_02) ); RAM_512_8 Lp2_03 ( .clka (clk), .wea (wea2_03), .addra(addr_wr2_03), .dina (din2_03), .clkb (clk), .addrb(addr_rd2_03), .doutb(dout2_03) ); RAM_512_8 Lp2_04 ( .clka (clk), .wea (wea2_04), .addra(addr_wr2_04), .dina (din2_04), .clkb (clk), .addrb(addr_rd2_04), .doutb(dout2_04) ); reg flag_switch_MS = 1'd0; always @(posedge clk) begin if (rst_MS) flag_switch_MS <= 1'd0; else begin if (nd_MS && cnt_MS == 11'd2047) flag_switch_MS <= ~flag_switch_MS; else flag_switch_MS <= flag_switch_MS; end end // 乒乓写缓存过程 always @(posedge clk) begin if (rst_MS) begin wea1_01 <= 1'd0; wea1_02 <= 1'd0; wea1_03 <= 1'd0; wea1_04 <= 1'd0; wea2_01 <= 1'd0; wea2_02 <= 1'd0; wea2_03 <= 1'd0; wea2_04 <= 1'd0; addr_wr1_01 <= 9'd511; addr_wr1_02 <= 9'd511; addr_wr1_03 <= 9'd511; addr_wr1_04 <= 9'd511; addr_wr2_01 <= 9'd511; addr_wr2_02 <= 9'd511; addr_wr2_03 <= 9'd511; addr_wr2_04 <= 9'd511; din1_01 <= 8'd0; din1_02 <= 8'd0; din1_03 <= 8'd0; din1_04 <= 8'd0; din2_01 <= 8'd0; din2_02 <= 8'd0; din2_03 <= 8'd0; din2_04 <= 8'd0; end else begin if (nd_MS) //所有的写操作均在nd_MS有效时进行 if (flag_switch_MS == 1'd0) begin //写第一个缓存区 if (cnt_MS >= 11'd0 && cnt_MS < 11'd512) begin wea1_01 <= 1'd1; addr_wr1_01 <= addr_wr1_01 + 9'd1; din1_01 <= din_MS; end else if (cnt_MS >= 11'd512 && cnt_MS < 11'd1024) begin wea1_02 <= 1'd1; addr_wr1_02 <= addr_wr1_02 + 9'd1; din1_02 <= din_MS; wea1_01 <= 1'd0; end else if (cnt_MS >= 11'd1024 && cnt_MS < 11'd1536) begin wea1_03 <= 1'd1; addr_wr1_03 <= addr_wr1_03 + 9'd1; din1_03 <= din_MS; wea1_02 <= 1'd0; end else if (cnt_MS >= 11'd1536 && cnt_MS <= 11'd2047) begin wea1_04 <= 1'd1; addr_wr1_04 <= addr_wr1_04 + 9'd1; din1_04 <= din_MS; wea1_03 <= 1'd0; end end else begin if (cnt_MS >= 11'd0 && cnt_MS < 11'd512) begin wea2_01 <= 1'd1; addr_wr2_01 <= addr_wr2_01 + 9'd1; din2_01 <= din_MS; end else if (cnt_MS >= 11'd512 && cnt_MS < 11'd1024) begin wea2_02 <= 1'd1; addr_wr2_02 <= addr_wr2_02 + 9'd1; din2_02 <= din_MS; wea2_01 <= 1'd0; end else if (cnt_MS >= 11'd1024 && cnt_MS < 11'd1536) begin wea2_03 <= 1'd1; addr_wr2_03 <= addr_wr2_03 + 9'd1; din2_03 <= din_MS; wea2_02 <= 1'd0; end else if (cnt_MS >= 11'd1536 && cnt_MS <= 11'd2047) begin wea2_04 <= 1'd1; addr_wr2_04 <= addr_wr2_04 + 9'd1; din2_04 <= din_MS; wea2_03 <= 1'd0; end end else begin wea1_01 <= 1'd0; wea1_02 <= 1'd0; wea1_03 <= 1'd0; wea1_04 <= 1'd0; wea2_01 <= 1'd0; wea2_02 <= 1'd0; wea2_03 <= 1'd0; wea2_04 <= 1'd0; din1_01 <= 8'd0; din1_02 <= 8'd0; din1_03 <= 8'd0; din1_04 <= 8'd0; din2_01 <= 8'd0; din2_02 <= 8'd0; din2_03 <= 8'd0; din2_04 <= 8'd0; addr_wr1_01 <= addr_wr1_01; addr_wr1_02 <= addr_wr1_02; addr_wr1_03 <= addr_wr1_03; addr_wr1_04 <= addr_wr1_04; addr_wr2_01 <= addr_wr2_01; addr_wr2_02 <= addr_wr2_02; addr_wr2_03 <= addr_wr2_03; addr_wr2_04 <= addr_wr2_04; end end end reg flag_out = 1'd0; reg [10:0] cnt_out_MS = 11'd0; // 产生输出计数器 always @(posedge clk) begin if (rst_MS) begin flag_out <= 1'd0; cnt_out_MS <= 11'd0; end else begin if (oe_MS) begin flag_out <= 1'd1; cnt_out_MS <= 11'd0; end else begin if (flag_out && cnt_out_MS < 11'd540) begin cnt_out_MS <= cnt_out_MS + 11'd1; end else begin flag_out <= 1'd0; cnt_out_MS <= cnt_out_MS; end end end end // 控制输出缓存地址 always @(posedge clk) begin if (rst_MS) begin addr_rd1_01 <= 9'd511; addr_rd1_02 <= 9'd511; addr_rd1_03 <= 9'd511; addr_rd1_04 <= 9'd511; addr_rd2_01 <= 9'd511; addr_rd2_02 <= 9'd511; addr_rd2_03 <= 9'd511; addr_rd2_04 <= 9'd511; end else begin if (flag_switch_MS) begin // 输出缓存1中的数据 if (cnt_out_MS >= 11'd1 && cnt_out_MS <= 11'd512) begin addr_rd1_01 <= addr_rd1_01 + 9'd1; addr_rd1_02 <= addr_rd1_02 + 9'd1; addr_rd1_03 <= addr_rd1_03 + 9'd1; addr_rd1_04 <= addr_rd1_04 + 9'd1; end else begin addr_rd1_01 <= 9'd511; addr_rd1_02 <= 9'd511; addr_rd1_03 <= 9'd511; addr_rd1_04 <= 9'd511; end end else begin // 输出缓存2中的数据 if (cnt_out_MS >= 11'd1 && cnt_out_MS <= 11'd512) begin addr_rd2_01 <= addr_rd2_01 + 9'd1; addr_rd2_02 <= addr_rd2_02 + 9'd1; addr_rd2_03 <= addr_rd2_03 + 9'd1; addr_rd2_04 <= addr_rd2_04 + 9'd1; end else begin addr_rd2_01 <= 9'd511; addr_rd2_02 <= 9'd511; addr_rd2_03 <= 9'd511; addr_rd2_04 <= 9'd511; end end end end // 输出缓存数据到译码器 always @(posedge clk) begin if (rst_MS) begin dout01_MS <= 8'd0; dout02_MS <= 8'd0; dout03_MS <= 8'd0; dout04_MS <= 8'd0; end else begin if (flag_switch_MS) begin if (cnt_out_MS >= 11'd5 && cnt_out_MS <= 11'd516) begin dout01_MS <= dout1_01; dout02_MS <= dout1_02; dout03_MS <= dout1_03; dout04_MS <= dout1_04; end else begin dout01_MS <= 8'd0; dout02_MS <= 8'd0; dout03_MS <= 8'd0; dout04_MS <= 8'd0; end end else begin if (cnt_out_MS >= 11'd5 && cnt_out_MS <= 11'd516) begin dout01_MS <= dout2_01; dout02_MS <= dout2_02; dout03_MS <= dout2_03; dout04_MS <= dout2_04; end else begin dout01_MS <= 8'd0; dout02_MS <= 8'd0; dout03_MS <= 8'd0; dout04_MS <= 8'd0; end end end end // 输出处理完成、同步脉冲和使能标志 assign deal_end_MS = (cnt_MS == 11'd2047 && nd_MS) ? 1'd1 : 1'd0; assign syncout_MS = (cnt_out_MS == 11'd5) ? 1'd1 : 1'd0; assign rdy_MS = (cnt_out_MS >= 11'd6 && cnt_out_MS <= 11'd517) ? 1'd1 : 1'd0; endmodule