📄 hssdrc_decoder_state.v
字号:
//--------------------------------------------------------------------------------------------------
always_comb begin : fsm_jump_decode
next_state = STATE_RESET;
unique case (1'b1)
state [STATE_RESET_BIT] : begin
next_state = STATE_IDLE;
end
state [STATE_IDLE_BIT] : begin
if (arb_write | arb_read | arb_refr)
next_state = STATE_DECODE;
else
next_state = STATE_IDLE;
end
//
// decode branch
//
state [STATE_DECODE_BIT] : begin
if (refr_mode) begin : shorten_refresh_decode
if (ba_map_all_close)
next_state = STATE_REFR;
else
next_state = STATE_PRE_ALL;
end
else begin : mode_of_rw_decode
if (ba_map_pre_act_rw)
next_state = STATE_PRE;
else if (ba_map_rw)
next_state = STATE_RW;
else // if (ba_map_act_rw)
next_state = STATE_ACT;
end
end
//
// pre branch
//
state [STATE_PRE_BIT] : begin
if (dec_pre_enable)
if (cTrp_m1 == 0)
next_state = STATE_ACT;
else
next_state = STATE_TRP;
else
next_state = STATE_PRE;
end
state [STATE_TRP_BIT] : begin
if (trp_cnt_done)
next_state = STATE_ACT;
else
next_state = STATE_TRP;
end
//
// act branch
//
state [STATE_ACT_BIT] : begin
if (dec_act_enable)
if (cTrcd_m1 == 0)
next_state = STATE_RW;
else
next_state = STATE_TRCD;
else
next_state = STATE_ACT;
end
state [STATE_TRCD_BIT] : begin
if (trcd_cnt_done)
next_state = STATE_RW;
else
next_state = STATE_TRCD;
end
//
// data branch
//
state [STATE_RW_BIT] : begin
if ((dec_write_enable & write_mode) | (dec_read_enable & ~write_mode)) begin : burst_done_decode
if (burst_done)
next_state = STATE_IDLE;
else
next_state = STATE_ADDR_INC;
end
else begin
next_state = STATE_RW;
end
end
state [STATE_ADDR_INC_BIT] : begin
next_state = STATE_RW;
end
//
// refresh breanch
//
state [STATE_PRE_ALL_BIT] : begin
if (dec_pre_all_enable)
next_state = STATE_REFR;
else
next_state = STATE_PRE_ALL;
end
state [STATE_REFR_BIT] : begin
if (dec_refr_enable)
next_state = STATE_IDLE;
else
next_state = STATE_REFR;
end
endcase
end
//---------------------------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------------------------
always_ff @(posedge clk or posedge reset) begin : fsm_register_process
if (reset) state <= STATE_RESET;
else if (sclr) state <= STATE_RESET;
else state <= next_state;
end
//---------------------------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------------------------
assign arb_ready = state[STATE_IDLE_BIT];
assign dec_pre_all = state[STATE_PRE_ALL_BIT];
assign dec_refr = state[STATE_REFR_BIT];
assign dec_pre = state[STATE_PRE_BIT];
assign dec_act = state[STATE_ACT_BIT];
assign dec_read = state[STATE_RW_BIT] & ~write_mode;
assign dec_write = state[STATE_RW_BIT] & write_mode;
assign dec_last = state[STATE_RW_BIT] & burst_done ;
//
// instead of decode state_refr_bit & state_pre_all_bit we can use refresh mode register
//
assign dec_locked = refr_mode;
//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
assign ba_map_update = state[STATE_DECODE_BIT] & ~refr_mode;
assign ba_map_clear = state[STATE_DECODE_BIT] & refr_mode;
always_ff @(posedge clk) begin : mode_logic
if (state [STATE_IDLE_BIT]) begin
refr_mode <= arb_refr;
write_mode <= arb_write;
end
end
//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
always_ff @(posedge clk) begin : addr_chid_logic
if (state[STATE_IDLE_BIT]) begin
rowa_latched <= arb_rowa;
ba_latched <= arb_ba;
chid_latched <= arb_chid;
end
if (state[STATE_IDLE_BIT])
cola_latched <= arb_cola;
else if (state[STATE_ADDR_INC_BIT])
cola_latched <= cola_latched + last_used_burst;
end
assign dec_cola = cola_latched;
assign dec_rowa = rowa_latched;
assign dec_ba = ba_latched;
assign dec_chid = chid_latched;
//--------------------------------------------------------------------------------------------------
// alligned burst max cycles is 4
// burst [3:2] == 0 & burst[1:0] <= available_burst. 1 cycle is burst
// burst [3:2] != 0 & burst[1:0] <= available_burst. 1 cycle is burst shift_cnt burst_done
// burst [ 1.. 4] : encoded with [ 4'd0 : 4'd3] : cycle is 1 : burst_shift_cnt = 4'b0000 1
// burst [ 5.. 8] : encoded with [ 4'd4 : 4'd7] : cycle is 2 : burst_shift_cnt = 4'b0001 0
// burst [ 9..12] : encoded with [ 4'd8 : 4'd11] : cycle is 3 : burst_shift_cnt = 4'b0010 0
// burst [13..16] : encoded with [4'd12 : 4'd15] : cycle is 4 : burst_shift_cnt = 4'b0100 0
//
// not alligned burst max cycles is 5 shift_cnt burst_done
// burst [ 1.. 4] : encoded with [ 4'd0 : 4'd3] : cycle is 2 : burst_shift_cnt = 4'b0001 0
// burst [ 5.. 8] : encoded with [ 4'd4 : 4'd7] : cycle is 3 : burst_shift_cnt = 4'b0010 0
// burst [ 9..12] : encoded with [ 4'd8 : 4'd11] : cycle is 4 : burst_shift_cnt = 4'b0100 0
// burst [13..16] : encoded with [4'd12 : 4'd15] : cycle is 5 : burst_shift_cnt = 4'b1000 0
//--------------------------------------------------------------------------------------------------
always_ff @(posedge clk) begin : burst_latch_logic
if (state[STATE_IDLE_BIT])
burst_latched = arb_burst;
end
// remember that burst has -1 offset
// available burst has -1 offset too
assign available_burst = 4'b0011 - {2'b00, cola_latched[1:0]};
assign remained_burst = burst_latched - available_burst - 1'b1;
assign remained_burst_high = remained_burst[3:2];
assign remained_burst_low = remained_burst[1:0];
assign early_burst_done = burst_shift_cnt[0];
always_ff @(posedge clk) begin : burst_logic
if (state[STATE_DECODE_BIT]) begin
if (burst_latched <= available_burst) begin
burst_shift_cnt <= '0;
burst_done <= 1'b1; // only 1 transaction will be
dec_burst <= burst_latched[1:0];
end
else begin
burst_shift_cnt <= '0;
burst_shift_cnt[remained_burst_high] <= 1'b1;
remained_burst_low_latched <= remained_burst_low;
burst_done <= 1'b0; // more then 2 transaction will be
dec_burst <= available_burst[1:0];
last_used_burst <= {2'b00, available_burst[1:0]} + 1'b1; // + 1 is compensation of -1 offset
end
end
else if (state[STATE_ADDR_INC_BIT]) begin
burst_shift_cnt <= burst_shift_cnt >> 1;
burst_done <= early_burst_done;
//
if (early_burst_done)
dec_burst <= remained_burst_low_latched; // no transaction any more
else
dec_burst <= 2'b11;
//
last_used_burst <= 4'b0011 + 1'b1;
end
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -