Commit 1dea2934 authored by Iulian Gheorghiu's avatar Iulian Gheorghiu

Fix LPM and LPM Z+ instruction.

Fix the LD instruction when load RAM value in the same register that provide the RAM address. Fix the LDD/STD instruction when load RAM value in the same register that provide the RAM address & incorrect addition of the offset value to the base address.
parent aeb1fe44
......@@ -617,6 +617,7 @@ begin
SEL_INSTRUCTION_SUBI |
SEL_INSTRUCTION_INC |
SEL_INSTRUCTION_DEC |
SEL_INSTRUCTION_LPM_R_P |
SEL_INSTRUCTION_CP |
SEL_INSTRUCTION_CPI) cin_int <= 1'b0;
end
......@@ -1087,32 +1088,6 @@ assign data_out = data_out_int;
assign data_in_int = data_in;
/*
* pgm_addr bus switcher
*/
always @ (*)
begin
if(CORE_CONFIG != "REDUCED")
begin
`ifdef USE_LPM
case(step_cnt)
`STEP2:
begin
casex(tmp_pgm_data)
`INSTRUCTION_LPM_R,
`INSTRUCTION_LPM_R_P: pgm_addr <= pgm_indirect_addr;
default: pgm_addr <= PC;
endcase
end
default: pgm_addr <= PC;
endcase
`endif
end
else
begin
pgm_addr <= PC;
end
end
/*
* ! pgm_addr bus switcher
*/
......@@ -1187,6 +1162,32 @@ int_encoder # (
.executed(current_int_executed)
);
/*
* pgm_addr bus switcher
*/
always @ (*)
begin
if(CORE_CONFIG != "REDUCED")
begin
`ifdef USE_LPM
case(step_cnt)
`STEP2:
begin
casex(tmp_pgm_data)
`INSTRUCTION_LPM_R,
`INSTRUCTION_LPM_R_P: pgm_addr <= pgm_indirect_addr[{1'b0, BUS_ADDR_PGM_WIDTH-1}:1];
default: pgm_addr <= PC;
endcase
end
default: pgm_addr <= PC;
endcase
`endif
end
else
begin
pgm_addr <= PC;
end
end
wire SEL_S1_INSTRUCTION_MOVW;
......@@ -1345,6 +1346,7 @@ reg SEL_S2_INSTRUCTION_LD_ST_YZP;
reg SEL_S2_INSTRUCTION_LD_ST_YZN;
reg SEL_S2_INSTRUCTION_LPM_R;
reg SEL_S2_INSTRUCTION_LPM_R_P;
reg SEL_S2_INSTRUCTION_LD_ST_X;
reg SEL_S2_INSTRUCTION_LD_ST_XP;
reg SEL_S2_INSTRUCTION_LD_ST_XN;
reg SEL_S2_INSTRUCTION_RET;
......@@ -1607,7 +1609,7 @@ begin
begin
rd_addr_r <= {{3{1'b1}}, ~tmp_pgm_data_switched[3], 1'b0};
rd_16bit_r <= 1'b1;
indirect_addr_offset <= {{11{1'b0}}, tmp_pgm_data_switched[11:10], tmp_pgm_data_switched[2:0]};
indirect_addr_offset <= {{10{1'b0}}, tmp_pgm_data_switched[13], tmp_pgm_data_switched[11:10], tmp_pgm_data_switched[2:0]};
if(tmp_pgm_data_switched[9])
begin
rd_addr_d <= tmp_pgm_data_switched[8:4];
......@@ -1620,7 +1622,8 @@ begin
// Connect busses
rw_data <= data_in_int;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
if(ram_read_delay == 0)
write_to_reg <= 1'b1;
data_re_int <= 1'b1;
end
end
......@@ -1628,35 +1631,36 @@ begin
if(SEL_S1_INSTRUCTION_LPM_R |
SEL_S1_INSTRUCTION_LPM_R_P)
begin
rd_addr_d <= pgm_data_int[8:4];
rd_addr_d <= 'h1E;//pgm_data_int[8:4];
rd_16bit_d <= 1'b1;
if(pgm_data_int[0])
begin
// Connect busses
alu_in_1 <= rd_data_d;
alu_in_2 <= 1;
rw_addr <= pgm_data_int[8:4];
rw_addr <= 'h1E;//pgm_data_int[8:4];
rw_data <= alu_out;
rw_16bit <= 1'b1;
write_to_reg <= 1'b1;
end
end
`endif
end/*!CORE_CONFIG != "REDUCED"*/
if(CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL")
begin
if(SEL_S1_INSTRUCTION_LD_ST_X)
/*if(SEL_S1_INSTRUCTION_LD_ST_X)
begin
rd_addr_r <= 5'd26;
rd_16bit_r <= 1'b1;
if(pgm_data_int[9])
begin
rd_addr_d <= pgm_data_int[8:4];
rd_addr_d <= tmp_pgm_data_switched[8:4];
data_out_int <= rd_data_d;
data_we_int <= 1'b1;
end
else
begin
rw_addr <= pgm_data_int[8:4];
rw_addr <= tmp_pgm_data_switched[8:4];
// Connect busses
rw_data <= data_in_int;
// Signalize write_to_reg;
......@@ -1664,7 +1668,7 @@ begin
data_re_int <= 1'b1;
end
end
end*/
if(SEL_S1_INSTRUCTION_LD_ST_YZP |
SEL_S1_INSTRUCTION_LD_ST_YZN)
begin
......@@ -1672,6 +1676,7 @@ begin
rd_16bit_r <= 1'b1;
rw_addr <= {{3{1'b1}}, ~tmp_pgm_data_switched[3], 1'b0};
//rw_16bit <= 1'b1;
//rw_16bit <= 1'b1;
if(tmp_pgm_data_switched[9])
begin
rd_addr_d <= tmp_pgm_data_switched[8:4];
......@@ -1684,17 +1689,20 @@ begin
// Connect busses
rw_data <= data_in_int;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
if(ram_read_delay == 0)
write_to_reg <= 1'b1;
data_re_int <= 1'b1;
end
end
if(SEL_S1_INSTRUCTION_LD_ST_XP |
if(SEL_S1_INSTRUCTION_LD_ST_X |
SEL_S1_INSTRUCTION_LD_ST_XP |
SEL_S1_INSTRUCTION_LD_ST_XN)
begin
rd_addr_r <= 5'd26;
rd_16bit_r <= 1'b1;
rw_addr <= 5'd26;
//rw_16bit <= 1'b1;
//rw_16bit <= 1'b1;
if(tmp_pgm_data_switched[9])
begin
rd_addr_d <= tmp_pgm_data_switched[8:4];
......@@ -1707,7 +1715,8 @@ begin
// Connect busses
rw_data <= data_in_int;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
if(ram_read_delay == 0)
write_to_reg <= 1'b1;
data_re_int <= 1'b1;
end
end
......@@ -1742,7 +1751,8 @@ begin
// Connect busses
rw_data <= data_in_int;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
if(ram_read_delay == 0)
write_to_reg <= 1'b1;
data_re_int <= 1'b1;
end
end
......@@ -1968,9 +1978,9 @@ begin
if(SEL_S2_INSTRUCTION_LPM_R |
SEL_S2_INSTRUCTION_LPM_R_P)
begin
rw_addr <= 0;
rw_data <= pgm_data_int;
rw_16bit <= 1'b1;
rw_addr <= tmp_pgm_data[8:4];
rw_data <= pgm_indirect_addr[0] ? pgm_data_int[15:8] : pgm_data_int[7:0];
rw_16bit <= 1'b0;
// Signalize write_to_reg;
write_to_reg <= 1'b1;
end
......@@ -2103,14 +2113,16 @@ begin
end
end
end
if(SEL_S2_INSTRUCTION_LD_ST_XP |
SEL_S2_INSTRUCTION_LD_ST_XN)
if(SEL_S2_INSTRUCTION_LD_ST_X |
SEL_S2_INSTRUCTION_LD_ST_XP |
SEL_S2_INSTRUCTION_LD_ST_XN)
begin
rd_addr_r <= 5'd26;
rd_16bit_r <= 1'b1;
rw_addr <= 5'd26;
rw_16bit <= 1'b1;
case(tmp_pgm_data[1:0])
2'b00: rw_data <= rd_data_r;
2'b01: rw_data <= rd_data_r_PLUS_ONE;
2'b10: rw_data <= rd_data_r_MINUS_ONE;
endcase
......@@ -2215,6 +2227,24 @@ begin
ALU_FLAGS[5] <= 1'b0; //Half Carry Flag
ALU_FLAGS[6] <= 1'b0; //Transfer bit used by BLD and BST instructions
ALU_FLAGS[7] <= 1'b0; //Global Interrupt Enable/Disable Flag
SEL_S2_INSTRUCTION_CPSE <= 'h0;
SEL_S2_INSTRUCTION_LDS_STS <= 'h0;
SEL_S2_INSTRUCTION_LD_ST_YZP <= 'h0;
SEL_S2_INSTRUCTION_LD_ST_YZN <= 'h0;
SEL_S2_INSTRUCTION_LPM_R <= 'h0;
SEL_S2_INSTRUCTION_LPM_R_P <= 'h0;
SEL_S2_INSTRUCTION_LD_ST_X <= 'h0;
SEL_S2_INSTRUCTION_LD_ST_XP <= 'h0;
SEL_S2_INSTRUCTION_LD_ST_XN <='h0 ;
SEL_S2_INSTRUCTION_RET <= 'h0;
SEL_S2_INSTRUCTION_RETI <= 'h0;
SEL_S2_INSTRUCTION_ICALL <= 'h0;
SEL_S2_INSTRUCTION_JMP <= 'h0;
SEL_S2_INSTRUCTION_CALL <= 'h0;
SEL_S2_INSTRUCTION_SBIC_SBIS <= 'h0;
SEL_S2_INSTRUCTION_MUL <= 'h0;
SEL_S2_INSTRUCTION_RCALL <= 'h0;
SEL_S2_INSTRUCTION_SBRC_SBRS <= 'h0;
PC <= 'h0000;
SP <= 'h0000;
current_int_executed <= 1'b0;
......@@ -2270,6 +2300,7 @@ begin
SEL_S2_INSTRUCTION_LD_ST_YZN <= SEL_S1_INSTRUCTION_LD_ST_YZN;
SEL_S2_INSTRUCTION_LPM_R <= SEL_S1_INSTRUCTION_LPM_R;
SEL_S2_INSTRUCTION_LPM_R_P <= SEL_S1_INSTRUCTION_LPM_R_P;
SEL_S2_INSTRUCTION_LD_ST_X <= SEL_S1_INSTRUCTION_LD_ST_X;
SEL_S2_INSTRUCTION_LD_ST_XP <= SEL_S1_INSTRUCTION_LD_ST_XP;
SEL_S2_INSTRUCTION_LD_ST_XN <=SEL_S1_INSTRUCTION_LD_ST_XN ;
SEL_S2_INSTRUCTION_RET <= SEL_S1_INSTRUCTION_RET;
......@@ -2289,10 +2320,10 @@ begin
if(int_request && ALU_FLAGS[7] && VECTOR_INT_TABLE_SIZE != 0)
begin
case(step_cnt)
`STEP1:
/*`STEP1:
begin
if(ram_read_delay == 0 &&
(SEL_S1_INSTRUCTION_LDD_STD && ~tmp_pgm_data_switched[9]) ||
//(SEL_S1_INSTRUCTION_LDD_STD && ~tmp_pgm_data_switched[9]) ||
(SEL_S1_INSTRUCTION_POP_PUSH && ~tmp_pgm_data_switched[9]))
begin
if(current_int_vect)
......@@ -2303,7 +2334,7 @@ begin
int_rst <= 1'b1 << (current_int_vect - 1);
end
end
end
end */
`STEP2:
begin
if(ram_read_delay == 0 &&
......@@ -2313,6 +2344,7 @@ begin
(SEL_S2_INSTRUCTION_MUL && (CORE_CONFIG != "CLASSIC_8K" && CORE_CONFIG != "CLASSIC_128K")) ||
((SEL_S2_INSTRUCTION_LD_ST_YZP ||
SEL_S2_INSTRUCTION_LD_ST_YZN ||
SEL_S2_INSTRUCTION_LD_ST_X ||
SEL_S2_INSTRUCTION_LD_ST_XP ||
SEL_S2_INSTRUCTION_LD_ST_XN) && ~pgm_data_int[9]) ||
(SEL_S2_INSTRUCTION_JMP && (CORE_CONFIG != "REDUCED" && CORE_CONFIG != "MINIMAL" && CORE_CONFIG != "CLASSIC_8K")) ||
......@@ -2329,7 +2361,7 @@ begin
begin
interrupt_registered <= 1'b1;
current_int_vect_int <= current_int_vect;
PC <= PC - 1;
PC <= PC + 1;
int_rst <= 1'b1 << (current_int_vect - 1);
end
end
......@@ -2453,6 +2485,7 @@ begin
SEL_S1_INSTRUCTION_LPM_R_P)
begin
tmp_pgm_data <= pgm_data_int;
pgm_indirect_addr <= rd_data_d[BUS_ADDR_PGM_WIDTH-1:0];
step_cnt <= `STEP2;
end
`endif
......@@ -2504,6 +2537,7 @@ begin
end
if(SEL_S1_INSTRUCTION_LD_ST_YZP |
SEL_S1_INSTRUCTION_LD_ST_YZN |
SEL_S1_INSTRUCTION_LD_ST_X |
SEL_S1_INSTRUCTION_LD_ST_XP |
SEL_S1_INSTRUCTION_LD_ST_XN)
begin
......@@ -2520,15 +2554,17 @@ begin
end
else
begin
ram_read_delay <= `USE_RAM_READ_DELAY;
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
PC <= PC;
end
end
else
begin
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
PC <= PC;
tmp_pgm_data <= pgm_data_int;
step_cnt <= `STEP2;
PC <= PC;
end
`else
tmp_pgm_data <= pgm_data_int;
......@@ -2637,7 +2673,7 @@ begin
if(SEL_S2_INSTRUCTION_LPM_R |
SEL_S2_INSTRUCTION_LPM_R_P)
begin
pgm_indirect_addr <= rd_data_d[BUS_ADDR_PGM_WIDTH-1:0];
PC <= PC;
end
`endif
end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment