- 易迪拓培训,专注于微波、射频、天线设计工程师的培养
基于网络编码的多信源组播通信系统,包括源代码,原理 等(四)
4结论
网络编码从提出到现在已有十年,在这期间,网络编码的理论研究和工程应用不断发展和成熟,基于网络编码的多信源组播系统是网络编码在硬件方面的实现。它突破了以往网络编码的应用研究只停留在软件和虚拟网络,通过搭建实际的组播通信网络,并应用NetFPGA平台使网络编码在硬件中得以实现。
文档的前面分别介绍了网络编码的基本概念和研究动态、编解码策略和算法以及编码、转发、解码三个系统的详细设计方案,包括系统的软硬接口和软件的基本功能。由于系统中的网络编解码都是由硬件完成,软件的功能主要是控制和测试时使用,因此方案设计以硬件为主。
图4-1,图4-2和图4-3分别是编码、转发以及解码路由器三个系统的verilog代码树状图,除去MAC层和core generator产生的代码,代码量有11,000行。附录给出了编码路由器和解码路由器中的关键代码。
图4-1 编码路由器代码树状图
图4-2 转发路由器代码树状图
图4-3 解码路由器代码树状图
附录
附1:编码路由器核心代码:编码模块: payload_router.v
/////////////////////////////////////////////////////////////////////////////
// vim:set shiftwidth=3 softtabstop=3 expandtab:
// Copyright(c) 2009, All rights reserved.
// Advanced Network technology Lab, Shenzhen graduated school of PKU
// Module: payload_router.v
// Project: nf2_coding.ise
// Time and Author: 2009-12-25 liyining
// Description:determine whether should carry out coding operation, and route
// the packets
/////////////////////////////////////////////////////////////////////////////
`define DLY 1
`timescale 1ns/1ns
module payload_router
#(parameter DATAWIDTH = 64,
parameter CTRLWIDTH = DATAWIDTH / 8 //bit-width parameter
)
(
//payload fifo 1 port
input [DATAWIDTH - 1:0] data_payloadfifo_router_1,
input [CTRLWIDTH - 1:0] ctrl_payloadfifo_router_1,
input empty_payloadfifo_router_1,
output reg rd_en_payloadfifo_router_1,
//payload fifo 2 port
input [DATAWIDTH - 1:0] data_payloadfifo_router_2,
input [CTRLWIDTH - 1:0] ctrl_payloadfifo_router_2,
input empty_payloadfifo_router_2,
output reg rd_en_payloadfifo_router_2,
//multiplier 1 port
input rdy_router_multiplier_1,
output reg [DATAWIDTH - 1:0] data_router_multiplier_1,
output reg first_dword_1, //flag to indicate the start of a pkt. only when it is the first double word of a pkt, should the random number be updated.
output reg val_router_multiplier_1,
//multiplier 2 port
input rdy_router_multiplier_2,
output reg [DATAWIDTH - 1:0] data_router_multiplier_2,
output reg first_dword_2, //flag to indicate the start of a pkt. only when it is the first double word of a pkt, should the random number be updated.
output reg val_router_multiplier_2,
//rand number generator port
output reg rand_num_en, //enable the random number generator
input rand_num_val,
//packing fifo port
input rdy_router_packingfifo,
input empty_packingfifo, // only when the whole last pkt is sent out, and the packing fifo is empty, then proceed the next pkt
output reg [DATAWIDTH + CTRLWIDTH:0] data_router_packingfifo, //an extra bit(MSB) to indicate whether it is a coded pkt
output reg val_router_packingfifo,
output reg [2:0] router_status, //send router_status to packing_fifo, indicate where to get data
//misc
input clk,
input rst_n
);
reg [DATAWIDTH - 1:0] data_temp1;
reg [CTRLWIDTH - 1:0] ctrl_temp1;
reg [DATAWIDTH - 1:0] data_temp2;
reg [CTRLWIDTH - 1:0] ctrl_temp2;
reg [1:0] counter_getdata; //counter for the read-FIFO-delay, 1 clock circle
parameter JUDGE = 3'b000;
parameter GET_DATA2 = 3'b001;
parameter SEND_DATA2 = 3'b010;
parameter GET_DATA1 = 3'b011;
parameter SEND_DATA1 = 3'b100;
parameter GET_BOTH = 3b101;
[p]parameter GET_BOTH = 3'b101;
parameter SEND_BOTH_1 = 3'b110;
parameter SEND_BOTH_2 = 3'b111;
always @(posedge clk or negedge rst_n) begin
//reset process
if (rst_n == 0) begin
router_status <= JUDGE;
data_temp1 <= 64'h0;
ctrl_temp1 <= 8'h0;
data_temp2 <= 64'h0;
ctrl_temp2 <= 8'h0;
counter_getdata <= 2'b0;
end
else begin
case (router_status)
JUDGE: begin
first_dword_1 <= 0;
first_dword_2 <= 0;
rand_num_en <= 0;
val_router_multiplier_2 <= 0; //clear some signals
//program hold, when packing FIFO inempty
if (!empty_packingfifo) begin
router_status <= JUDGE;
end
else begin
//both FIFO ctrl payload 1 & 2 are empty
if (empty_payloadfifo_router_1 && empty_payloadfifo_router_2) begin
rd_en_payloadfifo_router_1 <= 0;
rd_en_payloadfifo_router_2 <= 0;
router_status <= JUDGE;
end
//FIFO ctrl paylaod 2 is inempty, read from this FIFO,
//coding will be unnecessary
else if (empty_payloadfifo_router_1 && (!empty_payloadfifo_router_2)) begin
rd_en_payloadfifo_router_2 <= 1;
rd_en_payloadfifo_router_1 <= 0;
counter_getdata <= 0;
router_status <= GET_DATA2;
end
//FIFO ctrl payload 1 is inempty, read from this FIFO,
//coding will be unnecessary
else if ((!empty_payloadfifo_router_1) && empty_payloadfifo_router_2) begin
rd_en_payloadfifo_router_1 <= 1;
rd_en_payloadfifo_router_2 <= 0;
counter_getdata <= 0;
router_status <= GET_DATA1;
end
//both FIFO ctrl payload 1&2 are inempty, read from both
//of them, coding is needed
else if ((!empty_payloadfifo_router_1) && (!empty_payloadfifo_router_2)) begin
rd_en_payloadfifo_router_1 <= 1;
rd_en_payloadfifo_router_2 <= 1;
counter_getdata <= 0;
router_status <= GET_BOTH;
end
end
end //state JUDGE ends
//read data from FIFO ctrl payload 2
GET_DATA2: begin
val_router_packingfifo <= 0; //clear the output valid signal
//read-FIFO-delay
if (counter_getdata < 2'b01) begin
counter_getdata <= counter_getdata + 1;
router_status <= GET_DATA2;
rd_en_payloadfifo_router_2 <= 0; //clear rd_en signal
end
else begin
data_temp2 <= data_payloadfifo_router_2;
ctrl_temp2 <= ctrl_payloadfifo_router_2;
router_status <= SEND_DATA2;
end
end //state GET_DATA2 ends
//send data to packing fifo without coding
SEND_DATA2: begin
if (!rdy_router_packingfifo) begin
router_status <= SEND_DATA2;
[p]
end
else begin
data_router_packingfifo <= {ctrl_temp2, 1'b0 , data_temp2 }; //MSB = 0 means it is an uncoded pkt
val_router_packingfifo <= 1;
//this is the end of a packet, goto JUDGE
if (& (ctrl_temp2)) begin
router_status <= JUDGE;
end
//this is not the end of a packet, goto GET_DATA2
else begin
router_status <= GET_DATA2;
rd_en_payloadfifo_router_2 <= 1;
counter_getdata <= 0;
end
end
end //state SEND_DATA2 ends GET_DATA1: begin
val_router_packingfifo <= 0; //clear output valid signal
//read-FIFO-delay
if (counter_getdata < 2'b01) begin
counter_getdata <= counter_getdata + 1;
router_status <= GET_DATA1;
rd_en_payloadfifo_router_1 <= 0; //clear rd_en signal
end
else begin
data_temp1 <= data_payloadfifo_router_1;
ctrl_temp1 <= ctrl_payloadfifo_router_1;
rd_en_payloadfifo_router_1 <= 0;
router_status <= SEND_DATA1;
end
end //state GET_DATA1 ends
SEND_DATA1: begin
if (!rdy_router_packingfifo) begin
router_status <= SEND_DATA1;
end
else begin
data_router_packingfifo <= {ctrl_temp1, 1'b0 , data_temp1 }; //MSB = 0 means it is an uncoded pkt
val_router_packingfifo <= 1;
//this is the end of a packet, goto JUDGE
if (& (ctrl_temp1)) begin
router_status <= JUDGE;
end
//this is not the end of a packet, goto GET_DATA1
else begin
router_status <= GET_DATA1;
rd_en_payloadfifo_router_1 <= 1;
counter_getdata <= 0;
end
end
end //state SEND_DATA1 ends
GET_BOTH: begin
first_dword_2 <= 0; //
val_router_multiplier_2 <= 0; //clear valid signal
//read-FIFO-delay
if (counter_getdata < 2'b01) begin
counter_getdata <= counter_getdata + 1;
router_status <= GET_BOTH;
rd_en_payloadfifo_router_1 <= 0;
rd_en_payloadfifo_router_2 <= 0; //clear rd_en signals
end
else begin
data_temp1 <= data_payloadfifo_router_1;
ctrl_temp1 <= ctrl_payloadfifo_router_1;
data_temp2 <= data_payloadfifo_router_2;
ctrl_temp2 <= ctrl_payloadfifo_router_2;
router_status <= SEND_BOTH_1;
end
end //state GET_BOTH ends
//according to the random number generator, data from both
//input channels should be sent out seperately
SEND_BOTH_1: begin
if (!rdy_router_multiplier_1) begin
val_router_multiplier_1 <= 0;
router_status <= SEND_BOTH_1;
end
else
[p]else begin
data_router_multiplier_1 <= data_temp1;
val_router_multiplier_1 <= 1;
if (ctrl_temp1 == 8'hff) begin
first_dword_1 <= 1;
rand_num_en <= 1;
end
else begin
first_dword_1 <=0;
rand_num_en <= 0;
end
router_status <= SEND_BOTH_2;
end
end //state SEND_BOTH_1 ends
SEND_BOTH_2: begin
first_dword_1 <= 0;
val_router_multiplier_1 <= 0; //clear valid signal
//confirm the first random number is generated successfully
//before enable to generate the second.
if (ctrl_temp1 == 8'hff) begin
if (!rand_num_val) begin
rand_num_en <= 0;
router_status <= SEND_BOTH_2;
end
end else begin
if (!rdy_router_multiplier_2) begin
val_router_multiplier_2 <= 0;
router_status <= SEND_BOTH_2;
end
else begin
data_router_multiplier_2 <= data_temp2;
val_router_multiplier_2 <= 1;
if (ctrl_temp2 == 8'hff) begin
first_dword_2 <= 1;
rand_num_en <= 1;
end
else begin
first_dword_2 <= 0;
rand_num_en <= 0;
end
if (((ctrl_temp1 == 8'hf0) && (& (ctrl_temp2))) || ((ctrl_temp2 == 8'hf0) && (& (ctrl_temp1)))) begin
router_status <= JUDGE;
end
else begin
rd_en_payloadfifo_router_1 <= 1;
rd_en_payloadfifo_router_2 <= 1;
counter_getdata <= 0;
router_status <= GET_BOTH;
end
end
end
end //state SEND_BOTH_2 ends
endcase
end
end
endmodule
附2:解码路由器核心代码之一:解码控制模块:decode_control_sm. v
///////////////////////////////////////////////////////////////////////////////
// vim:set shiftwidth=3 softtabstop=3 expandtab:
// Copyright(c) 2009, All rights reserved.
// Advanced Network technology Lab, Shenzhen graduated school of PKU
// Module: decode_control_sm.v
// Project: NF2.1
// Time and Author: 2009-12-15 zhang ming long
// Description: According to the pkts' source and generation sequence number,
// this module goes round-robin strategy to control the module decoder
// to decode the pkts stored in DRAMS.
///////////////////////////////////////////////////////////////////////////////
`define DLY #1
`timescale 1ns/1ps
module decode_control_sm
#(parameter SRC_WIDTH = 4,
parameter GEN_WIDTH = 8,
parameter REG_GRP_WIDTH = 12,
parameter SRC_GEN_SEQ_WIDTH = 24,
parameter DRAM_NUMS = 3,
parameter CAM_NUMS = 3,
parameter DRAM_NUMS_WIDTH = log2(DRAM_NUMS),
parameter CAM_NUMS_WIDTH = log2(CAM_NUMS),
parameter DRAM_BLOCK_WIDTH = 8,
parameter CAM_ADDR_WIDTH = 8,
parameter CMP_DATA_MASK = 12'hfff
)
(// --- cam interface
output [SRC_GEN_SEQ_WIDTH-1:0] cmp_data_0,
output reg [SRC_GEN_SEQ_WIDTH-1:0] cmp_data_mask_0,
input [CAM_ADDR_WIDTH-1:0] match_addr_0,
input match_0,
output [SRC_GEN_SEQ_WIDTH-1:0]
[p]output [SRC_GEN_SEQ_WIDTH-1:0] cmp_data_1,
output reg [SRC_GEN_SEQ_WIDTH-1:0] cmp_data_mask_1,
input [CAM_ADDR_WIDTH-1:0] match_addr_1,
input match_1,
output [SRC_GEN_SEQ_WIDTH-1:0] cmp_data_2,
output reg [SRC_GEN_SEQ_WIDTH-1:0] cmp_data_mask_2,
input [CAM_ADDR_WIDTH-1:0] match_addr_2,
input match_2,
// ---DRAM control interface
output reg [DRAM_NUMS_WIDTH-1:0] port_num_rd,
output reg [DRAM_BLOCK_WIDTH-1:0] block_num_rd,
output reg addr_vld,
input rd_idle,
// ---input_arbiter interface
input cam_vld,
// ---decoder interface
output reg pkt_vld,
output reg [REG_GRP_WIDTH-1:0] pkt_dcoding,
output reg pkt_not_find,
output reg has_other_factor,
input [REG_GRP_WIDTH-1:0] pkt_need_src_gen,
input need_pkt_vld,
input decod_com,
// ---decoded reg grp interface
output reg rd_dcod_reg_req_1,
output [REG_GRP_WIDTH-1:0] rd_dcod_src_gen_1,
input req_ack_vld_1,
input alredy_decod_1,
// --- Misc
input rst_n,
input clk
); function integer log2;
input integer number;
begin
log2=0;
while(2**log2 log2=log2+1; end end endfunction // log2 // ------------ Internal Params -------- parameter NUM_STATES = 4; parameter IDLE = 4'b0; parameter GET_SRC_GEN_NUM = 4'b0001; parameter LOOK_UP_CAM = 4'b0010; parameter GET_CMP_RESLT_FIRST = 4'b0011; parameter GET_CMP_RESLT_SEC = 4'b0100; parameter RD_DRAM_MAIN_STEP = 4'b0101; parameter LUP_DCOD_FACTOR1_FIRST = 4'b0110; parameter LUP_DCOD_FACTOR1_SEC = 4'b0111; parameter GET_FACTOR1_RESLT = 4'b1000; parameter RD_DRAM_MINOR_STEP = 4'b1001; parameter LUP_DCOD_FACTOR2 = 4'b1011; // ------------- Regs/ wires ----------- wire [SRC_WIDTH-1:0] src_num_plus1; reg [SRC_WIDTH-1:0] src_num,src_num_sel,src_num_sel_next; //source sequence number for packets that is being decoded reg [SRC_WIDTH-1:0] src_num_next; wire [GEN_WIDTH-1:0] gen_num_plus1; reg [GEN_WIDTH-1:0] gen_num,gen_num_sel,gen_num_sel_next; //generation sequence number for packets that is being decoded reg [GEN_WIDTH-1:0] gen_num_next; reg [CAM_NUMS-1:0] cam_lookup_reslt; // result of looking up packets in cam,stands for which cam finds the packet reg [CAM_NUMS-1:0] cam_lookup_reslt_next; reg[CAM_NUMS-1:0] cam_lookup_reslt_pre,cam_lookup_reslt_save; reg[CAM_NUMS-1:0] cam_lookup_reslt_pre_next,cam_lookup_reslt_save_next; reg [CAM_ADDR_WIDTH-1:0] other_dram_addr; reg [CAM_ADDR_WIDTH-1:0] other_dram_addr_next; reg [DRAM_NUMS_WIDTH-1:0] other_port_num_rd; //the other result from looking up cams reg has_factor2; //has the other looking up result reg has_factor2_next; reg has_factor2_next; reg [DRAM_NUMS_WIDTH-1:0] other_port_num_rd_next; reg [NUM_STATES-1:0] state; reg [NUM_STATES-1:0] state_next; reg [4:0] couter; wire [4:0] couter_next; reg couter_start; reg[CAM_ADDR_WIDTH-1:0] atch_addr_temp_2,match_addr_temp_2_next; reg[CAM_ADDR_WIDTH-1:0] match_addr_temp_1,match_addr_temp_1_next; reg[CAM_ADDR_WIDTH-1:0] match_addr_temp_0,match_addr_temp_0_next; reg [SRC_GEN_SEQ_WIDTH-1:0] cmp_data; // ------------ main code and logic ------------- assign src_num_plus1 = (src_num == 2)
0 : src_num + 1; assign gen_num_plus1 = (gen_num == 2**GEN_WIDTH-1)
0 : gen_num + 1; assign rd_dcod_src_gen_1 = {src_num_sel,gen_num_sel}; assign couter_next = (couter_start == 1)
couter+1 : couter; assign cmp_data_0 = cmp_data; assign cmp_data_1 = cmp_data; assign cmp_data_2 = cmp_data; /* This state machine completes decode control task. If enough packets have * been saved in cams and DRAMS, it starts to decode to packets. If * a packet can not be decoded becouse of losing, it will decode the next * packet automatically */ always @(*) begin state_next = state; gen_num_next = gen_num; src_num_next = src_num; src_num_sel_next = src_num_sel; gen_num_sel_next = gen_num_sel; cam_lookup_reslt_next = cam_lookup_reslt; rd_dcod_reg_req_1 = 1'b0; addr_vld = 1'b0; pkt_vld = 1'b0; pkt_not_find = 1'b0; other_dram_addr_next = other_dram_addr; other_port_num_rd_next =other_port_num_rd; has_factor2_next = has_factor2; pkt_dcoding = 12'hfff; block_num_rd = 2'b0; cam_lookup_reslt_pre_next = cam_lookup_reslt_pre; cam_lookup_reslt_save_next = cam_lookup_reslt_save; port_num_rd = 2'b11; couter_start = 1'b0; match_addr_temp_2_next = match_addr_temp_2; match_addr_temp_1_next = match_addr_temp_1; match_addr_temp_0_next = match_addr_temp_0; cmp_data_mask_0 = 24'h0; cmp_data_mask_1 = 24'h0; cmp_data_mask_2 = 24'h0; has_other_factor = 0; cmp_data = 24'hffffff; case(state) /* --- waiting for the cam has been writen enough packet */ IDLE: begin if(cam_vld) begin couter_start = 1; end if(couter == 5'b11111) state_next = GET_SRC_GEN_NUM; end /* Goes round-robin around the sources and generations, * gets the source sequence number and generation sequebce * number of a packet need to be decoded */ GET_SRC_GEN_NUM: begin state_next = LOOK_UP_CAM; rd_dcod_reg_req_1 = 1; // read the decoded reg grp src_num_sel_next = src_num; gen_num_sel_next = gen_num; src_num_next = src_num_plus1; if(src_num == 4'b0010) gen_num_next = gen_num_plus1; end /* --- look up pkt in three cams to get block number of DRAM*/ LOOK_UP_CAM: if(req_ack_vld_1) begin if(alredy_decod_1 == 1) // it has been decoded,decode the next packet state_next = GET_SRC_GEN_NUM; else begin cmp_data = {src_num_sel,gen_num_sel,12'hfff}; cmp_data_mask_0 = {12'h0,CMP_DATA_MASK}; cmp_data_mask_1 = {12'h0,CMP_DATA_MASK}; cmp_data_mask_2 = {12'h0,CMP_DATA_MASK}; state_next = GET_CMP_RESLT_FIRST; end end GET_CMP_RESLT_FIRST: begin cam_lookup_reslt_next = {match_2,match_1,match_0}; cmp_data = {12'hfff,src_num_sel,gen_num_sel}; cmp_data_mask_0 = {CMP_DATA_MASK,12'h0}; cmp_data_mask_1 = {CMP_DATA_MASK,12'h0}; cmp_data_mask_2 = {CMP_DATA_MASK,12'h0}; state_next = GET_CMP_RESLT_SEC; match_addr_temp_2_next = match_addr_2; match_addr_temp_1_next = match_addr_1; match_addr_temp_0_next = match_addr_0; end /* get the address from the cams, if there are two adresses from * the cams, then outputs the one to the DRAM control and save * * the other for later use. If there is no valid address, we could not * decode, then get out and decode the next one */ GET_CMP_RESLT_SEC: begin state_next = RD_DRAM_MAIN_STEP; cam_lookup_reslt_next = cam_lookup_reslt | {match_2,match_1,match_0}; cam_lookup_reslt_pre_next = cam_lookup_reslt | {match_2,match_1,match_0}; cam_lookup_reslt_save_next = cam_lookup_reslt | {match_2,match_1,match_0}; if(match_2) begin match_addr_temp_2_next = match_addr_2; end if(match_1) begin match_addr_temp_1_next = match_addr_1; end if(match_0) begin match_addr_temp_0_next = match_addr_0; end end /* reads the DRAM accroding to the CAM's address, then updates the look * up result */ RD_DRAM_MAIN_STEP: if(rd_idle) begin if(|cam_lookup_reslt) begin if(cam_lookup_reslt==3'b101) begin other_dram_addr_next = match_addr_temp_2; other_port_num_rd_next = 2'b10; has_factor2_next = 1; addr_vld = 1; block_num_rd = match_addr_temp_0; port_num_rd = 0; cam_lookup_reslt_next = 3'b100; end else if (cam_lookup_reslt == 3'b011) begin other_dram_addr_next = match_addr_temp_1; other_port_num_rd_next = 2'b01; has_factor2_next = 1; addr_vld = 1; block_num_rd = match_addr_temp_0; port_num_rd = 0; cam_lookup_reslt_next = 3'b010; end else if (cam_lookup_reslt==3'b110) begin other_dram_addr_next = match_addr_temp_2; other_port_num_rd_next = 2'b10; has_factor2_next = 1; addr_vld = 1; block_num_rd = match_addr_temp_1; port_num_rd = 2'b01; cam_lookup_reslt_next=3'b100; end else if (cam_lookup_reslt==3'b001) begin has_factor2_next = 0; addr_vld = 1; block_num_rd = match_addr_0; port_num_rd = 2'b00; cam_lookup_reslt_next = 0; end else if (cam_lookup_reslt==3'b010) begin has_factor2_next = 0; addr_vld = 1; block_num_rd = match_addr_1; port_num_rd = 2'b01; cam_lookup_reslt_next = 0; end else if (cam_lookup_reslt==3'b100) begin has_factor2_next = 0; addr_vld = 1; block_num_rd = match_addr_2; port_num_rd = 2'b10; cam_lookup_reslt_next = 0; end state_next=LUP_DCOD_FACTOR1_FIRST; pkt_vld = 1; pkt_dcoding = {src_num_sel,gen_num_sel}; end // end-- if(|cam_lookup_reslt) else state_next = GET_SRC_GEN_NUM; //could not find the pkt in cams. end //end--if(rd_idle) /* waiting for decoding completion, if needs the decoding factor pkt, * then look up the factor in the remain cams */ LUP_DCOD_FACTOR1_FIRST: begin if(decod_com) begin state_next=GET_SRC_GEN_NUM; end if(need_pkt_vld) begin // need other packet to decode current packet if((cam_lookup_reslt^~cam_lookup_reslt_pre)==3'b110) begin cmp_data = {pkt_need_src_gen,12'hfff}; cmp_data_mask_2 = {12'h0,CMP_DATA_MASK}; cmp_data_mask_1 = {12'h0,CMP_DATA_MASK}; end else if((cam_lookup_reslt^~cam_lookup_reslt_pre)==3'b101) begin cmp_data = {pkt_need_src_gen,12'hfff}; cmp_data_mask_2 = {12'h0,CMP_DATA_MASK}; cmp_data_mask_0 = {12'h0,CMP_DATA_MASK}; end else if((cam_lookup_reslt^~cam_lookup_reslt_pre)==3'b011) begin cmp_data = {pkt_need_src_gen,12'hfff}; cmp_data_mask_1 = {12'h0,CMP_DATA_MASK}; cmp_data_mask_0 = {12'h0,CMP_DATA_MASK}; end else if((cam_lookup_reslt^~cam_lookup_reslt_pre)==3'b001) begin cmp_data = {pkt_need_src_gen,12'hfff}; cmp_data_mask_0 = {12'h0,CMP_DATA_MASK}; end else if((cam_lookup_reslt^~cam_lookup_reslt_pre)==3'b010) begin cmp_data = {pkt_need_src_gen,12'hfff}; cmp_data_mask_1 = {12'h0,CMP_DATA_MASK}; end else if((cam_lookup_reslt^~cam_lookup_reslt_pre)==3'b100) begin cmp_data = {pkt_need_src_gen,12'hfff}; cmp_data_mask_2 = {12'h0,CMP_DATA_MASK}; end state_next = LUP_DCOD_FACTOR1_SEC; end end LUP_DCOD_FACTOR1_SEC: begin state_next = GET_FACTOR1_RESLT; cam_lookup_reslt_next = {match_2,match_1,match_0}; match_addr_temp_2_next = match_addr_2; match_addr_temp_1_next = match_addr_1; match_addr_temp_0_next = match_addr_0; if((cam_lookup_reslt^~cam_lookup_reslt_pre)==3'b110) begin cmp_data = {12'hfff,pkt_need_src_gen}; cmp_data_mask_2 = {CMP_DATA_MASK,12'h0}; cmp_data_mask_1 = {CMP_DATA_MASK,12'h0}; end else if((cam_lookup_reslt^~cam_lookup_reslt_pre)==3'b101) begin cmp_data = {12'hfff,pkt_need_src_gen}; cmp_data_mask_2 = {CMP_DATA_MASK,12'h0}; cmp_data_mask_0 = {CMP_DATA_MASK,12'h0}; end else if((cam_lookup_reslt^~cam_lookup_reslt_pre)==3'b011) begin cmp_data = {12'hfff,pkt_need_src_gen}; cmp_data_mask_0 = {CMP_DATA_MASK,12'h0}; cmp_data_mask_1 = {CMP_DATA_MASK,12'h0}; end else if((cam_lookup_reslt^~cam_lookup_reslt_pre)==3'b001) begin cmp_data = {12'hfff,pkt_need_src_gen}; cmp_data_mask_0 = {CMP_DATA_MASK,12'h0}; end else if((cam_lookup_reslt^~cam_lookup_reslt_pre)==3'b010) begin cmp_data = {12'hfff,pkt_need_src_gen}; cmp_data_mask_1 = {CMP_DATA_MASK,12'h0}; end else if((cam_lookup_reslt^~cam_lookup_reslt_pre)==3'b100) begin cmp_data = {12'hfff,pkt_need_src_gen}; cmp_data_mask_2 = {CMP_DATA_MASK,12'h0}; end end /* --- get the factor pkt address from the cam, then reads the DRAM if no address matches, then check the decode factor2 */ GET_FACTOR1_RESLT: begin state_next = RD_DRAM_MINOR_STEP; cam_lookup_reslt_next = cam_lookup_reslt | {match_2,match_1,match_0}; cam_lookup_reslt_pre_next = cam_lookup_reslt | {match_2,match_1,match_0}; if(match_2) begin match_addr_temp_2_next = match_addr_2; end if(match_1) begin match_addr_temp_1_next = match_addr_1; end if(match_0) begin match_addr_temp_0_next = match_addr_0; end end RD_DRAM_MINOR_STEP: if(rd_idle) if(|cam_lookup_reslt) begin state_next = LUP_DCOD_FACTOR1_FIRST; if(cam_lookup_reslt==3'b001) begin addr_vld = 1; block_num_rd = match_addr_temp_0; port_num_rd = 2'b00; cam_lookup_reslt_next=0; end else if (cam_lookup_reslt==3'b010) begin addr_vld = 1; block_num_rd = match_addr_temp_1; port_num_rd = 2'b01; cam_lookup_reslt_next=0; end else if (cam_lookup_reslt==3'b100) begin addr_vld = 1; block_num_rd = match_addr_temp_2; port_num_rd = 2'b10; cam_lookup_reslt_next=0; end end else begin state_next = LUP_DCOD_FACTOR2; pkt_not_find = 1; has_other_factor = has_factor2; end /* decoding the packet by decode factor2 */ LUP_DCOD_FACTOR2: if(has_factor2) begin addr_vld = 1; block_num_rd = other_dram_addr; port_num_rd = other_port_num_rd; state_next = LUP_DCOD_FACTOR1_FIRST; cam_lookup_reslt_pre_next = cam_lookup_reslt_save; has_factor2_next = 0; end else begin pkt_not_find = 1; has_other_factor = has_factor2; state_next = GET_SRC_GEN_NUM; end endcase // case(state) end // always @ (*) always @(posedge clk) begin src_num_sel <= `DLY src_num_sel_next; gen_num_sel <= `DLY gen_num_sel_next; cam_lookup_reslt_pre <= `DLY cam_lookup_reslt_pre_next; other_dram_addr <= `DLY other_dram_addr_next; other_port_num_rd <= `DLY other_port_num_rd_next; match_addr_temp_2 <= `DLY match_addr_temp_2_next; match_addr_temp_1 <= `DLY match_addr_temp_1_next; match_addr_temp_0 <= `DLY match_addr_temp_0_next; cam_lookup_reslt_save <= `DLY cam_lookup_reslt_save_next; end always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) begin state <= IDLE; src_num <= 0; gen_num <= 0; has_factor2 <= 0; cam_lookup_reslt <= 0; couter <= 5'b0; end else begin state <= `DLY state_next; src_num <= `DLY src_num_next; gen_num <= `DLY gen_num_next; couter <= `DLY couter_next; cam_lookup_reslt <= `DLY cam_lookup_reslt_next; has_factor2 <= `DLY has_factor2_next; end end endmodule //decode_control_sm
射频工程师养成培训教程套装,助您快速成为一名优秀射频工程师...
天线设计工程师培训课程套装,资深专家授课,让天线设计不再难...
上一篇:如何正确理解TL431的工作方式
下一篇:关于快速充电技术的探讨