• 易迪拓培训,专注于微波、射频、天线设计工程师的培养
首页 > 电子设计 > 电源技术 > 电源技术 > 基于网络编码的多信源组播通信系统,包括源代码,原理 等(四)

基于网络编码的多信源组播通信系统,包括源代码,原理 等(四)

录入:edatop.com    点击:

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;

[p]

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

*

[p]

* 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};

[p]

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)

[p]

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的工作方式
下一篇:关于快速充电技术的探讨

射频和天线工程师培训课程详情>>

  网站地图