📄 rb1_decoder.v
字号:
module RB1_decoder(rangeOut, offsetOut, rom2_address, bin_0, modelValue_out, used_bin_num,
same_ctxIdxLPS, last_pStateIdx, readReg, ctxIdx, codIRange, codIOffset, rom2_in_data,
IsNotB0, modelValue_in, next_modelValue_in, group_effective, /*syntaxElement,
complement, */dec_mode, clk, rst);
output [8:0] rangeOut;
output [8:0] offsetOut;
output [5:0] rom2_address;
output bin_0;
output [6:0] modelValue_out;
output [3:0] used_bin_num; //how many bins the RB1 used.
output [31:0] same_ctxIdxLPS;
output [5:0] last_pStateIdx; //in case RB2_decoder decoding out of 'LPS', renew pStateIdx;
reg [8:0] rangeOut;
reg [8:0] offsetOut;
reg [5:0] rom2_address;
reg bin_0;
reg [6:0] modelValue_out; //send to RB2
reg [3:0] used_bin_num;
wire [31:0] same_ctxIdxLPS;
wire [5:0] last_pStateIdx;
input [15:0] readReg;
input [8:0] ctxIdx;
input [8:0] codIRange;
input [8:0] codIOffset;
input [111:0] rom2_in_data;
input IsNotB0;
input [6:0] modelValue_in; //obtain model
input [6:0] next_modelValue_in;
input group_effective; //1: indicate RAM is effective;
//input [4:0] syntaxElement;
//input [1:0] complement;
input [2:0] dec_mode;
input clk;
input rst;
reg [7:0] FODValue; //FOD input value (8 bits);
reg [2:0] FODNum; //FOD output value (3 bits);
reg [8:0] reserve_ctxIdx; //restore ctxIdx
reg [111:0] prefetched_rLPS; //pre-feteched rLPS;
reg [31:0] next_rangeLPS;
reg [39:0] last_rangeLPS; //+8 bits last state
reg [5:0] pStateIdx;
// reg rLPS_effective; //rLPS is effective
// reg IsPrefetched;
reg [8:0] rangeNew;
reg [8:0] offsetNew;
reg IsValMPS; //is valMPS in last cycles
// reg [2:0] position_rLPS; //Indicate which rLPS should be appled
reg [7:0] codIRangeLPS; //rLPS to decoded
// reg prefetched_load; //judge if load prefetched value;
//only rLPS_effective = 1
reg [1:0] samectxIdx_state; //to record the status of in same ctxIdx;
//reg [1:0] state, next_state; //not effecient to use state machine, because it waste a cycle
wire [1:0] qCodIRangeIdx; //qCodIRangeIdx = (codIRange >> 6) & 3;
wire valMPS;
assign qCodIRangeIdx = codIRange[7:6];
//assign valMPS = modelValue_in[6];
assign same_ctxIdxLPS = next_rangeLPS[31:0]; //
assign last_pStateIdx = last_rangeLPS[37:32];
always @(posedge clk or negedge rst)
begin
if(!rst)
begin
//rLPS_effective <= 0;
rom2_address <= 0;
// rangeOut <= 0;
// offsetOut <= 0;
// bin_0 <= 0;
// modelValue_out <= 0;
// used_bin_num <= 0;
reserve_ctxIdx <= 0;
// prefetch_rLPS <= 0;
// IsPrefetched <= 0;
// prefetched_load <= 0;
samectxIdx_state <= 0;
end
else
begin
if(group_effective)
begin
reserve_ctxIdx <= ctxIdx;
end
if(!IsNotB0)
begin
if(reserve_ctxIdx == ctxIdx)
begin
//rLPS_effective <= 1;
if(samectxIdx_state < 2) //maxim is 2
begin
samectxIdx_state <= samectxIdx_state + 1;
end
case(samectxIdx_state)
2'b00: //havn't pre-fetched next ctxIdx value
begin
rom2_address <= next_modelValue_in[5:0];
end
default: //have pre-fetched next ctxIdx value
begin
rom2_address <= pStateIdx;
end
endcase
end
else if(reserve_ctxIdx == (ctxIdx + 1)) //not effecient as I want.
begin
// rLPS_effective <= 1;
samectxIdx_state <= 0;
rom2_address <= modelValue_in[6:0]; //to obtain next 32-bits rLPS
// IsPrefetched <= 0;
// position_rLPS <= 3'b100;
end
else //Be careful! because RAM_management maybe not completed
begin
// rLPS_effective <= 0;
samectxIdx_state <= 0;
if(group_effective)
begin
// IsPrefetched <= 0;
// prefetched_load <= 0;
rom2_address <= modelValue_in[6:0];
samectxIdx_state <= 0;
end
end
end
else //IsNotB0, coeff_abs_level_minus1, continous decoded
begin
//IsPrefetched <= 0; //never to take ctxIdx + 1;
if(reserve_ctxIdx == ctxIdx)
begin
// rLPS_effective <= 1;
samectxIdx_state <= 0;
rom2_address <= pStateIdx + 2; //
// position_rLPS <= 3'b000;
end
else
begin
// rLPS_effective <= 0;
if(group_effective)
begin
rom2_address <= modelValue_in[5:0];
end
end
end
end
end
always @(codIRange or codIOffset or dec_mode or qCodIRangeIdx or samectxIdx_state or ctxIdx or reserve_ctxIdx or IsValMPS or modelValue_in or readReg or rom2_in_data)
begin
rangeNew = codIRange;
offsetNew = codIOffset;
codIRangeLPS = 0;
//prefetched_rLPS = 0;
if(((dec_mode == 3'b000) || (dec_mode == 3'b100)) && ((reserve_ctxIdx == ctxIdx) || (reserve_ctxIdx == (ctxIdx + 1))))
begin
if(reserve_ctxIdx == ctxIdx)
begin
case(samectxIdx_state)
0:
begin
case(qCodIRangeIdx)
2'b00:
begin
codIRangeLPS = rom2_in_data[39:32];
end
2'b01:
begin
codIRangeLPS = rom2_in_data[47:40];
end
2'b10:
begin
codIRangeLPS = rom2_in_data[55:48];
end
2'b11:
begin
codIRangeLPS = rom2_in_data[63:56];
end
endcase
next_rangeLPS = rom2_in_data[31:0];
last_rangeLPS = rom2_in_data[103:64];
end
2: //first state
begin
case(qCodIRangeIdx)
2'b00:
begin
codIRangeLPS = rom2_in_data[39:32];
end
2'b01:
begin
codIRangeLPS = rom2_in_data[47:40];
end
2'b10:
begin
codIRangeLPS = rom2_in_data[55:48];
end
2'b11:
begin
codIRangeLPS = rom2_in_data[63:56];
end
endcase
next_rangeLPS = rom2_in_data[31:0];
last_rangeLPS = rom2_in_data[103:64];
end
1: //second state
begin
prefetched_rLPS = rom2_in_data; //restore it
case({IsValMPS, qCodIRangeIdx})
3'b000:
begin
codIRangeLPS = last_rangeLPS[7:0];
end
3'b001:
begin
codIRangeLPS = last_rangeLPS[15:8];
end
3'b010:
begin
codIRangeLPS = last_rangeLPS[23:16];
end
3'b011:
begin
codIRangeLPS = last_rangeLPS[31:24];
end
3'b100:
begin
codIRangeLPS = next_rangeLPS[7:0];
end
3'b101:
begin
codIRangeLPS = next_rangeLPS[15:8];
end
3'b110:
begin
codIRangeLPS = next_rangeLPS[23:16];
end
3'b111:
begin
codIRangeLPS = next_rangeLPS[31:23];
end
endcase
end
default:
begin
codIRangeLPS = 0;
end
endcase
end
else //if(ctxIdx == (reserve_ctxIdx + 1))
begin
next_rangeLPS = prefetched_rLPS[31:0];
last_rangeLPS = prefetched_rLPS[103:64];
case(qCodIRangeIdx)
2'b00:
begin
codIRangeLPS = prefetched_rLPS[39:32];
end
2'b01:
begin
codIRangeLPS = prefetched_rLPS[47:40];
end
2'b10:
begin
codIRangeLPS = prefetched_rLPS[55:48];
end
2'b11:
begin
codIRangeLPS = prefetched_rLPS[63:56];
end
endcase
end
mainOperation; //main decoding process;
rangeOut = rangeNew;
offsetOut = offsetNew;
end
else if(ctxIdx == 276) //termination
begin
termination;
end
end
task mainOperation;
begin
rangeNew = rangeNew - codIRangeLPS;
if(offsetNew < rangeNew) //valMPS
begin
bin_0 = modelValue_in[6];
IsValMPS = 1;
pStateIdx = modelValue_in[5:0];
if(pStateIdx < 62)
begin
pStateIdx = pStateIdx + 1;
modelValue_out[5:0] = pStateIdx;
end
if(!rangeNew[8]) //codIRange < 0x100 need left shift one time
begin
rangeNew = rangeNew << 1;
offsetNew = offsetNew << 1;
offsetNew[0] = readReg[0];
used_bin_num = 1;
end
end
else //valLPS
begin
bin_0 = !modelValue_in[6]; //valure of LPS
IsValMPS = 0;
offsetNew = offsetNew - rangeNew;
rangeNew = codIRangeLPS;
pStateIdx = modelValue_in[5:0];
if(pStateIdx == 0)
begin
modelValue_out[6] = !modelValue_in[6]; //valMPS = 1 - valMPS
end
if(reserve_ctxIdx == ctxIdx)
pStateIdx = last_rangeLPS[37:32];
else if(reserve_ctxIdx == (ctxIdx + 1))
pStateIdx = prefetched_rLPS[101:96];
modelValue_out[5:0] = pStateIdx; //renew pStateIdx;
FODValue = rangeNew[7:0];
firstOneDetect;
used_bin_num = FODNum;
case(FODNum) //FODNum = 1--7
1:
begin
rangeNew = rangeNew << 1;
offsetNew = offsetNew << 1;
offsetNew[0] = readReg[0];
end
2:
begin
rangeNew = rangeNew << 2;
offsetNew = offsetNew << 2;
offsetNew[1:0] = readReg[1:0];
end
3:
begin
rangeNew = rangeNew << 3;
offsetNew = offsetNew << 3;
offsetNew[2:0] = readReg[2:0];
end
4:
begin
rangeNew = rangeNew << 4;
offsetNew = offsetNew << 4;
offsetNew[3:0] = readReg[3:0];
end
5:
begin
rangeNew = rangeNew << 5;
offsetNew = offsetNew << 5;
offsetNew[4:0] = readReg[4:0];
end
6:
begin
rangeNew = rangeNew << 6;
offsetNew = offsetNew << 6;
offsetNew = readReg[5:0];
end
7:
begin
rangeNew = rangeNew << 7;
offsetNew = offsetNew << 7;
offsetNew = readReg[6:0];
end
default:
begin
rangeNew = rangeNew << 1; //this should never be reached!
offsetNew = offsetNew << 1;
offsetNew = readReg[0];
end
endcase
end
end
endtask
task firstOneDetect;
reg out1;
begin
out1 = |FODValue[7:4];
if(out1)
begin
if(FODValue[7])
FODNum = 0;
else if(FODValue[6])
FODNum = 1;
else if(FODValue[5])
FODNum = 2;
else
FODNum = 3;
end
else
begin
if(FODValue[3])
FODNum = 0;
else if(FODValue[2])
FODNum = 1;
else if(FODValue[1])
FODNum = 2;
else
FODNum = 3;
FODNum = FODNum + 4;
end
end
endtask
task termination;
begin
rangeNew = rangeNew - 2;
if(offsetNew < rangeNew)
begin
bin_0 = 0;
if(!rangeNew[8]) //codIRange < 0x100 need left shift one time
begin
FODValue = rangeNew[7:0];
firstOneDetect;
//rangeNew = rangeNew << FODNum;
//offsetNew = offsetNew << FODNum;
case(FODNum) //FODNum = 1--7
1:
begin
rangeNew = rangeNew << 1;
offsetNew = offsetNew << 1;
offsetNew[0] = readReg[0];
end
2:
begin
rangeNew = rangeNew << 2;
offsetNew = offsetNew << 2;
offsetNew[1:0] = readReg[1:0];
end
3:
begin
rangeNew = rangeNew << 3;
offsetNew = offsetNew << 3;
offsetNew[2:0] = readReg[2:0];
end
4:
begin
rangeNew = rangeNew << 4;
offsetNew = offsetNew << 4;
offsetNew[3:0] = readReg[3:0];
end
5:
begin
rangeNew = rangeNew << 5;
offsetNew = offsetNew << 5;
offsetNew[4:0] = readReg[4:0];
end
6:
begin
rangeNew = rangeNew << 6;
offsetNew = offsetNew << 6;
offsetNew = readReg[5:0];
end
7:
begin
rangeNew = rangeNew << 7;
offsetNew = offsetNew << 7;
offsetNew = readReg[6:0];
end
default:
begin
rangeNew = rangeNew << 1; //this should never be reached!
offsetNew = offsetNew << 1;
offsetNew = readReg[0];
end
endcase
used_bin_num = FODNum;
end
else
begin
bin_0 = 1;
end
end
end
endtask
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -