Files
MM7020/hdl/Message_Store.v
T

386 lines
13 KiB
Verilog

`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