| 1 |
29 |
ns32kum |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
| 2 |
9 |
ns32kum |
//
|
| 3 |
|
|
// This file is part of the M32632 project
|
| 4 |
|
|
// http://opencores.org/project,m32632
|
| 5 |
|
|
//
|
| 6 |
23 |
ns32kum |
// Filename: ADDR_UNIT.v
|
| 7 |
29 |
ns32kum |
// Version: 3.0
|
| 8 |
|
|
// History: 2.0 of 11 August 2016
|
| 9 |
|
|
// 1.1 bug fix of 7 October 2015
|
| 10 |
23 |
ns32kum |
// 1.0 first release of 30 Mai 2015
|
| 11 |
29 |
ns32kum |
// Date: 2 December 2018
|
| 12 |
9 |
ns32kum |
//
|
| 13 |
29 |
ns32kum |
// Copyright (C) 2018 Udo Moeller
|
| 14 |
9 |
ns32kum |
//
|
| 15 |
|
|
// This source file may be used and distributed without
|
| 16 |
|
|
// restriction provided that this copyright statement is not
|
| 17 |
|
|
// removed from the file and that any derivative work contains
|
| 18 |
|
|
// the original copyright notice and the associated disclaimer.
|
| 19 |
|
|
//
|
| 20 |
|
|
// This source file is free software; you can redistribute it
|
| 21 |
|
|
// and/or modify it under the terms of the GNU Lesser General
|
| 22 |
|
|
// Public License as published by the Free Software Foundation;
|
| 23 |
|
|
// either version 2.1 of the License, or (at your option) any
|
| 24 |
|
|
// later version.
|
| 25 |
|
|
//
|
| 26 |
|
|
// This source is distributed in the hope that it will be
|
| 27 |
|
|
// useful, but WITHOUT ANY WARRANTY; without even the implied
|
| 28 |
|
|
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
| 29 |
|
|
// PURPOSE. See the GNU Lesser General Public License for more
|
| 30 |
|
|
// details.
|
| 31 |
|
|
//
|
| 32 |
|
|
// You should have received a copy of the GNU Lesser General
|
| 33 |
|
|
// Public License along with this source; if not, download it
|
| 34 |
|
|
// from http://www.opencores.org/lgpl.shtml
|
| 35 |
|
|
//
|
| 36 |
29 |
ns32kum |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
| 37 |
9 |
ns32kum |
//
|
| 38 |
|
|
// Modules contained in this file:
|
| 39 |
|
|
// ADDR_UNIT generates data access addresses and controls data cache operation
|
| 40 |
|
|
//
|
| 41 |
11 |
ns32kum |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
| 42 |
9 |
ns32kum |
|
| 43 |
11 |
ns32kum |
module ADDR_UNIT ( BCLK, BRESET, READ, WRITE, LDEA, NEWACC, CLRMSW, POST, DISP_OK, FULLACC, SRC2SEL, INDEX, ASIZE, SRC1, SRC2, BWD,
|
| 44 |
|
|
DISP, PC_ARCHI, PC_ICACHE, IO_READY, ACC_STAT, MMU_UPDATE, IC_TEX, ABO_STAT, ADIVAR, RWVAL_1, OP_RMW, PHASE_17,
|
| 45 |
29 |
ns32kum |
NO_TRAP, FPU_TRAP, READ_OUT, WRITE_OUT, ZTEST, RMW, VADR, ADDR, SIZE, PACKET, ACC_DONE, ABORT, CTRL_QW, BITSEL,
|
| 46 |
12 |
ns32kum |
QWATWO );
|
| 47 |
9 |
ns32kum |
|
| 48 |
|
|
input BCLK,BRESET;
|
| 49 |
|
|
input READ,WRITE,LDEA;
|
| 50 |
|
|
input NEWACC;
|
| 51 |
|
|
input CLRMSW,POST,FULLACC;
|
| 52 |
|
|
input [1:0] SRC2SEL;
|
| 53 |
|
|
input [3:0] INDEX;
|
| 54 |
|
|
input [1:0] ASIZE;
|
| 55 |
|
|
input [31:0] SRC1,SRC2;
|
| 56 |
|
|
input [1:0] BWD;
|
| 57 |
|
|
input [31:0] DISP;
|
| 58 |
|
|
input [31:0] PC_ARCHI,PC_ICACHE;
|
| 59 |
|
|
input DISP_OK;
|
| 60 |
|
|
input IO_READY;
|
| 61 |
|
|
input [5:0] ACC_STAT; // Feedback from data cache about the running access
|
| 62 |
|
|
input [1:0] MMU_UPDATE;
|
| 63 |
|
|
input [2:0] IC_TEX;
|
| 64 |
|
|
input [1:0] ABO_STAT;
|
| 65 |
|
|
input ADIVAR;
|
| 66 |
|
|
input RWVAL_1; // special access for RDVAL + WRVAL
|
| 67 |
|
|
input OP_RMW;
|
| 68 |
|
|
input PHASE_17;
|
| 69 |
|
|
input NO_TRAP;
|
| 70 |
|
|
input FPU_TRAP;
|
| 71 |
|
|
|
| 72 |
|
|
output READ_OUT,WRITE_OUT,ZTEST,RMW;
|
| 73 |
|
|
output [31:0] VADR;
|
| 74 |
|
|
output [31:0] ADDR;
|
| 75 |
|
|
output [1:0] SIZE;
|
| 76 |
|
|
output [3:0] PACKET;
|
| 77 |
|
|
output ACC_DONE;
|
| 78 |
|
|
output ABORT;
|
| 79 |
29 |
ns32kum |
output [1:0] CTRL_QW;
|
| 80 |
9 |
ns32kum |
output [2:0] BITSEL;
|
| 81 |
12 |
ns32kum |
output reg QWATWO;
|
| 82 |
9 |
ns32kum |
|
| 83 |
|
|
reg [31:0] VADR;
|
| 84 |
|
|
reg READ_OUT,write_reg,ZTEST,RMW;
|
| 85 |
|
|
reg [1:0] SIZE;
|
| 86 |
|
|
reg [3:0] PACKET;
|
| 87 |
|
|
reg [2:0] BITSEL;
|
| 88 |
|
|
reg [31:0] source2;
|
| 89 |
|
|
reg [31:0] index_val;
|
| 90 |
|
|
reg [31:0] vadr_reg;
|
| 91 |
|
|
reg [31:0] ea_reg;
|
| 92 |
|
|
reg [31:0] tos_offset;
|
| 93 |
|
|
reg [31:0] icache_adr;
|
| 94 |
|
|
reg [31:0] sign_ext_src1;
|
| 95 |
|
|
reg [31:12] pg_areg;
|
| 96 |
|
|
reg reg_out_i,next_reg;
|
| 97 |
|
|
reg ld_ea_reg;
|
| 98 |
|
|
reg acc_run,acc_ende,acc_step;
|
| 99 |
|
|
reg qwa_flag;
|
| 100 |
|
|
reg no_done;
|
| 101 |
|
|
reg frueh_ok;
|
| 102 |
|
|
reg io_rdy;
|
| 103 |
|
|
reg ABORT;
|
| 104 |
|
|
reg [1:0] tex_feld;
|
| 105 |
|
|
reg [2:0] u_ddt;
|
| 106 |
|
|
reg pg_op;
|
| 107 |
|
|
reg do_wr;
|
| 108 |
29 |
ns32kum |
reg irdy_flag;
|
| 109 |
9 |
ns32kum |
|
| 110 |
|
|
wire acc_ok,acc_err,io_acc;
|
| 111 |
|
|
wire acc_pass;
|
| 112 |
|
|
wire ca_hit;
|
| 113 |
|
|
wire [31:0] reg_adder;
|
| 114 |
|
|
wire [31:0] next_vadr;
|
| 115 |
|
|
wire [31:0] final_addr;
|
| 116 |
|
|
wire [31:0] pg_addr;
|
| 117 |
|
|
wire [1:0] inc_pack;
|
| 118 |
|
|
wire [3:0] index_sel;
|
| 119 |
|
|
wire ld_ea_i;
|
| 120 |
|
|
wire ea_ok;
|
| 121 |
|
|
wire qw_align;
|
| 122 |
|
|
wire init_acc;
|
| 123 |
|
|
wire in_page;
|
| 124 |
|
|
wire all_ok;
|
| 125 |
|
|
wire fa_out;
|
| 126 |
|
|
wire pg_test;
|
| 127 |
|
|
|
| 128 |
|
|
// ++++++++++++++++++++ Decoding ACC_STAT from data cache ++++++++++++++++++++++++++++
|
| 129 |
|
|
|
| 130 |
|
|
// ACC_STAT[5:0] : CA_HIT, IO_ACC, PROT_ERROR , ABO_LEVEL1 , ABORT , ACC_OK
|
| 131 |
|
|
|
| 132 |
|
|
assign ca_hit = ACC_STAT[5];
|
| 133 |
|
|
assign io_acc = ACC_STAT[4];
|
| 134 |
|
|
assign acc_err = ACC_STAT[3] | ACC_STAT[1]; // Abort or Protection Error
|
| 135 |
|
|
assign acc_ok = ACC_STAT[0] & ~pg_op;
|
| 136 |
|
|
assign acc_pass = ACC_STAT[0] & ZTEST;
|
| 137 |
|
|
|
| 138 |
|
|
always @(posedge BCLK) ABORT <= acc_err; // Signal to Steuerung - only a pulse
|
| 139 |
|
|
|
| 140 |
11 |
ns32kum |
always @(posedge BCLK) if (acc_err) tex_feld <= ACC_STAT[3] ? 2'b11 : {~ACC_STAT[2],ACC_STAT[2]}; // for MSR
|
| 141 |
9 |
ns32kum |
always @(posedge BCLK) if (acc_err) u_ddt <= {RMW,ABO_STAT[1],(WRITE_OUT | ZTEST)};
|
| 142 |
|
|
|
| 143 |
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
| 144 |
|
|
|
| 145 |
|
|
always @(SRC2SEL or CLRMSW or SRC2 or PC_ARCHI or ea_reg)
|
| 146 |
|
|
case (SRC2SEL)
|
| 147 |
11 |
ns32kum |
2'b00 : source2 = {(CLRMSW ? 16'h0000 : SRC2[31:16]),SRC2[15:0]}; // base reg, External Addressing with MOD
|
| 148 |
9 |
ns32kum |
2'b01 : source2 = PC_ARCHI; // PC relative
|
| 149 |
|
|
2'b10 : source2 = 32'h0; // Absolute Addressing
|
| 150 |
|
|
2'b11 : source2 = ea_reg; // REUSE : 2. TOS
|
| 151 |
|
|
endcase
|
| 152 |
|
|
|
| 153 |
11 |
ns32kum |
assign index_sel = POST ? 4'h0 : INDEX; // Alternative application of Index for POST Adder : POP from Stack
|
| 154 |
9 |
ns32kum |
|
| 155 |
|
|
always @(BWD or SRC1)
|
| 156 |
|
|
casex (BWD)
|
| 157 |
|
|
2'b00 : sign_ext_src1 = {{24{SRC1[7]}}, SRC1[7:0]}; // Byte
|
| 158 |
|
|
2'b01 : sign_ext_src1 = {{16{SRC1[15]}},SRC1[15:0]}; // Word
|
| 159 |
|
|
default : sign_ext_src1 = SRC1;
|
| 160 |
|
|
endcase
|
| 161 |
|
|
|
| 162 |
|
|
always @(index_sel or sign_ext_src1 or SRC1)
|
| 163 |
|
|
casex (index_sel)
|
| 164 |
29 |
ns32kum |
4'b1_0xx : index_val = sign_ext_src1; // f�r CASE
|
| 165 |
9 |
ns32kum |
4'b1_1xx : index_val = {{ 3{sign_ext_src1[31]}},sign_ext_src1[31:3]}; // for Bit Opcodes
|
| 166 |
|
|
4'b0_100 : index_val = SRC1;
|
| 167 |
|
|
4'b0_101 : index_val = {SRC1[30:0],1'b0};
|
| 168 |
|
|
4'b0_110 : index_val = {SRC1[29:0],2'b00};
|
| 169 |
|
|
4'b0_111 : index_val = {SRC1[28:0],3'b000};
|
| 170 |
|
|
default : index_val = 32'h0;
|
| 171 |
|
|
endcase
|
| 172 |
|
|
|
| 173 |
|
|
assign reg_adder = source2 + index_val; // SRC2 allows simple MOV with SRC1
|
| 174 |
|
|
|
| 175 |
|
|
assign final_addr = reg_adder + DISP; // That's the final access address
|
| 176 |
|
|
|
| 177 |
11 |
ns32kum |
always @(posedge BCLK) if (LDEA && (index_sel[3:2] == 2'b11)) BITSEL <= SRC1[2:0]; // for Bit Opcodes in I_PFAD
|
| 178 |
9 |
ns32kum |
|
| 179 |
|
|
always @(INDEX) // SP POP Operation & String Backward
|
| 180 |
|
|
case (INDEX[2:0])
|
| 181 |
|
|
3'b000 : tos_offset = 32'h0000_0001;
|
| 182 |
|
|
3'b001 : tos_offset = 32'h0000_0002;
|
| 183 |
|
|
3'b010 : tos_offset = 32'h0000_0004;
|
| 184 |
|
|
3'b011 : tos_offset = 32'h0000_0008;
|
| 185 |
|
|
3'b100 : tos_offset = 32'hFFFF_FFFF;
|
| 186 |
|
|
3'b101 : tos_offset = 32'hFFFF_FFFE;
|
| 187 |
|
|
3'b110 : tos_offset = 32'hFFFF_FFFC;
|
| 188 |
|
|
3'b111 : tos_offset = 32'hFFFF_FFF8;
|
| 189 |
|
|
endcase
|
| 190 |
|
|
|
| 191 |
|
|
always @(posedge BCLK or negedge BRESET)
|
| 192 |
|
|
if (!BRESET) ld_ea_reg <= 1'b0;
|
| 193 |
|
|
else ld_ea_reg <= (LDEA | ld_ea_reg) & ~DISP_OK;
|
| 194 |
|
|
|
| 195 |
|
|
assign ld_ea_i = (LDEA | ld_ea_reg) & DISP_OK;
|
| 196 |
|
|
|
| 197 |
|
|
assign ea_ok = (READ | WRITE | LDEA | ld_ea_reg) & ~FULLACC & DISP_OK;
|
| 198 |
|
|
|
| 199 |
|
|
always @(posedge BCLK) icache_adr <= PC_ICACHE;
|
| 200 |
|
|
|
| 201 |
|
|
// Memory for the calculated address for reuse and Register for POST modified addresses :
|
| 202 |
|
|
always @(posedge BCLK)
|
| 203 |
|
|
if (ld_ea_i)
|
| 204 |
|
|
begin
|
| 205 |
|
|
casex ({MMU_UPDATE[1],INDEX[0],POST})
|
| 206 |
|
|
3'b10x : ea_reg <= MMU_UPDATE[0] ? vadr_reg : icache_adr; // TEAR
|
| 207 |
|
|
3'b11x : ea_reg <= MMU_UPDATE[0] ?
|
| 208 |
|
|
{24'h0000_00,3'b101, u_ddt, tex_feld} // MSR
|
| 209 |
|
|
: {24'h0000_00,3'b100,IC_TEX[2],ABO_STAT[0],1'b0,IC_TEX[1:0]}; // only READ from ICACHE
|
| 210 |
|
|
3'b0x1 : ea_reg <= source2 + tos_offset ;
|
| 211 |
|
|
3'b0x0 : ea_reg <= final_addr;
|
| 212 |
|
|
endcase
|
| 213 |
|
|
end
|
| 214 |
|
|
|
| 215 |
|
|
assign ADDR = ea_reg; // used for ADDR opcode and TOS Addressing
|
| 216 |
|
|
|
| 217 |
|
|
// This pulse stores all parameters of access
|
| 218 |
11 |
ns32kum |
assign init_acc = ((FULLACC ? (NEWACC & acc_ende) : acc_ende) | ~acc_run) & DISP_OK & (READ | WRITE) & ~ABORT & NO_TRAP;
|
| 219 |
9 |
ns32kum |
|
| 220 |
|
|
assign fa_out = init_acc | ADIVAR; // special case for LMR IVAR,...
|
| 221 |
|
|
|
| 222 |
|
|
always @(fa_out or acc_ok or final_addr or qw_align or pg_op or pg_areg or vadr_reg or next_vadr)
|
| 223 |
|
|
casex ({fa_out,acc_ok})
|
| 224 |
|
|
2'b1x : VADR = {final_addr[31:3],(final_addr[2] | qw_align),final_addr[1:0]};
|
| 225 |
|
|
2'b00 : VADR = pg_op ? {pg_areg,12'h0} : vadr_reg;
|
| 226 |
|
|
2'b01 : VADR = next_vadr;
|
| 227 |
|
|
endcase
|
| 228 |
|
|
|
| 229 |
|
|
always @(posedge BCLK)
|
| 230 |
|
|
if (init_acc) vadr_reg <= {final_addr[31:3],(final_addr[2] | qw_align),final_addr[1:0]};
|
| 231 |
|
|
else
|
| 232 |
|
|
if (pg_op && ZTEST && acc_err) vadr_reg <= {pg_areg,12'h0}; // for TEAR !
|
| 233 |
|
|
else
|
| 234 |
|
|
if (acc_ok) vadr_reg <= next_vadr;
|
| 235 |
|
|
|
| 236 |
|
|
assign next_vadr = qwa_flag ? {vadr_reg[31:3],3'b000} : ({vadr_reg[31:2],2'b00} + 32'h0000_0004);
|
| 237 |
|
|
|
| 238 |
|
|
// Logic for Page border WRITE Test
|
| 239 |
|
|
assign pg_addr = final_addr + {29'h0,(ASIZE[1] & ASIZE[0]),ASIZE[1],(ASIZE[1] | ASIZE[0])};
|
| 240 |
|
|
always @(posedge BCLK) if (init_acc) pg_areg <= pg_addr[31:12];
|
| 241 |
|
|
assign pg_test = (final_addr[12] != pg_addr[12]) & ~OP_RMW; // At RMW no Test necessary
|
| 242 |
|
|
|
| 243 |
|
|
always @(posedge BCLK or negedge BRESET)
|
| 244 |
|
|
if (!BRESET) pg_op <= 1'b0;
|
| 245 |
|
|
else
|
| 246 |
|
|
pg_op <= init_acc ? (WRITE & ~RWVAL_1 & pg_test) : (pg_op & ~acc_pass & ~acc_err);
|
| 247 |
|
|
|
| 248 |
|
|
always @(posedge BCLK) do_wr <= pg_op & ZTEST & acc_pass; // All ok, Page exists => continue
|
| 249 |
|
|
|
| 250 |
|
|
always @(posedge BCLK or negedge BRESET)
|
| 251 |
|
|
if (!BRESET) READ_OUT <= 1'b0;
|
| 252 |
|
|
else
|
| 253 |
|
|
READ_OUT <= init_acc ? (READ & ~RWVAL_1) : (READ_OUT & ~acc_ende & ~acc_err);
|
| 254 |
|
|
|
| 255 |
|
|
always @(posedge BCLK or negedge BRESET)
|
| 256 |
|
|
if (!BRESET) write_reg <= 1'b0;
|
| 257 |
|
|
else
|
| 258 |
11 |
ns32kum |
write_reg <= (init_acc ? (WRITE & ~RWVAL_1 & ~pg_test) : (write_reg & ~acc_ende & ~acc_err & ~FPU_TRAP)) | do_wr;
|
| 259 |
9 |
ns32kum |
|
| 260 |
|
|
assign WRITE_OUT = write_reg & ~FPU_TRAP;
|
| 261 |
|
|
|
| 262 |
|
|
// Special case for RDVAL and WRVAL
|
| 263 |
|
|
always @(posedge BCLK or negedge BRESET)
|
| 264 |
|
|
if (!BRESET) ZTEST <= 1'b0;
|
| 265 |
|
|
else
|
| 266 |
11 |
ns32kum |
ZTEST <= pg_op ? (~ZTEST | (~acc_pass & ~acc_err)) : (init_acc ? RWVAL_1 : (ZTEST & ~acc_ende & ~acc_err));
|
| 267 |
9 |
ns32kum |
|
| 268 |
|
|
always @(posedge BCLK or negedge BRESET)
|
| 269 |
|
|
if (!BRESET) RMW <= 1'b0;
|
| 270 |
|
|
else
|
| 271 |
|
|
RMW <= init_acc ? (OP_RMW & PHASE_17) : (RMW & ~acc_ende & ~acc_err);
|
| 272 |
|
|
|
| 273 |
|
|
// Special case : first MSD access by aligned QWORD READ
|
| 274 |
|
|
assign qw_align = (final_addr[2:0] == 3'b000) & READ & (ASIZE == 2'b11);
|
| 275 |
|
|
|
| 276 |
|
|
always @(posedge BCLK) if (init_acc) qwa_flag <= qw_align;
|
| 277 |
|
|
|
| 278 |
|
|
always @(posedge BCLK or negedge BRESET) // central flag that shows the ADDR_UNIT is busy
|
| 279 |
|
|
if (!BRESET) acc_run <= 1'b0;
|
| 280 |
|
|
else
|
| 281 |
|
|
acc_run <= init_acc | (acc_run & ~acc_ende & ~acc_err & ~FPU_TRAP);
|
| 282 |
|
|
|
| 283 |
|
|
always @(posedge BCLK) if (init_acc) SIZE <= ASIZE;
|
| 284 |
|
|
|
| 285 |
|
|
assign inc_pack = (PACKET[1:0] == 2'b00) ? 2'b10 : {(SIZE[1] ^ SIZE[0]),(SIZE[1] & SIZE[0])};
|
| 286 |
|
|
|
| 287 |
11 |
ns32kum |
// Counter for data packets 1 to 3 : special case aligned QWORD : only 2 packets. Additionally start address in bits 1 und 0.
|
| 288 |
9 |
ns32kum |
// special coding (00) -> [01] -> (10) , [01] optional by QWORD and (10) shows always the end
|
| 289 |
|
|
always @(posedge BCLK)
|
| 290 |
|
|
if (init_acc) PACKET <= {2'b00,final_addr[1:0]};
|
| 291 |
|
|
else
|
| 292 |
|
|
if (acc_ok) PACKET <= PACKET + {inc_pack,2'b00};
|
| 293 |
|
|
|
| 294 |
|
|
// This signal is the End signal for the ADDR_UNIT internally.
|
| 295 |
|
|
always @(SIZE or PACKET or acc_ok)
|
| 296 |
|
|
casex ({SIZE,PACKET[3],PACKET[1:0]})
|
| 297 |
|
|
5'b00_x_xx : acc_ende = acc_ok; // Byte
|
| 298 |
|
|
5'b01_0_0x : acc_ende = acc_ok; // Word 1 packet
|
| 299 |
|
|
5'b01_0_10 : acc_ende = acc_ok; // 1 packet
|
| 300 |
|
|
5'b01_1_xx : acc_ende = acc_ok; // 2 packets
|
| 301 |
|
|
5'b10_0_00 : acc_ende = acc_ok; // DWord 1 packet
|
| 302 |
|
|
5'b10_1_xx : acc_ende = acc_ok; // 2 packets
|
| 303 |
|
|
5'b11_1_xx : acc_ende = acc_ok; // QWord at least 2 packets
|
| 304 |
|
|
default : acc_ende = 1'b0;
|
| 305 |
|
|
endcase
|
| 306 |
|
|
|
| 307 |
11 |
ns32kum |
assign in_page = (vadr_reg[11:3] != 9'h1FF); // Access inside a page ? During WRITE address is increasing : 1. LSD 2. MSD
|
| 308 |
9 |
ns32kum |
|
| 309 |
|
|
always @(SIZE or vadr_reg or in_page or PACKET)
|
| 310 |
|
|
casex (SIZE)
|
| 311 |
|
|
2'b01 : frueh_ok = (vadr_reg[3:2] != 2'b11); //Word
|
| 312 |
|
|
2'b10 : frueh_ok = (vadr_reg[3:2] != 2'b11); //DWord
|
| 313 |
11 |
ns32kum |
2'b11 : frueh_ok = (PACKET[1:0] == 2'b00) ? (~vadr_reg[3] | ~vadr_reg[2]) : ((PACKET[3:2] == 2'b01) & (vadr_reg[3:2] != 2'b11));
|
| 314 |
9 |
ns32kum |
default : frueh_ok = 1'b1; // Byte don't case
|
| 315 |
|
|
endcase
|
| 316 |
|
|
|
| 317 |
|
|
assign all_ok = SIZE[1] ? (PACKET[1:0] == 2'b00) : (PACKET[1:0] != 2'b11); // for DWord : Word
|
| 318 |
|
|
|
| 319 |
11 |
ns32kum |
always @(SIZE or READ_OUT or frueh_ok or PACKET or all_ok or io_acc or acc_ok or qwa_flag or io_rdy or ca_hit)
|
| 320 |
9 |
ns32kum |
casex ({SIZE,READ_OUT,frueh_ok,PACKET[3],io_acc,all_ok})
|
| 321 |
|
|
7'b00_xxxx_x : acc_step = acc_ok; // Byte, all ok
|
| 322 |
|
|
//
|
| 323 |
|
|
7'b01_xxxx_1 : acc_step = acc_ok; // Word : aligned access , only 1 packet
|
| 324 |
|
|
7'b01_1x1x_0 : acc_step = acc_ok; // READ must wait for all data
|
| 325 |
23 |
ns32kum |
7'b01_0x1x_0 : acc_step = acc_ok; // WRITE Adr. ist not perfect and waits for last packet
|
| 326 |
|
|
7'b01_0100_0 : acc_step = acc_ok; // WRITE Adr. perfect - acc_step after 1. packet
|
| 327 |
9 |
ns32kum |
//
|
| 328 |
|
|
7'b10_xxxx_1 : acc_step = acc_ok; // DWord : aligned access , only 1 packet
|
| 329 |
|
|
7'b10_1x1x_0 : acc_step = acc_ok; // READ must wait for all data
|
| 330 |
23 |
ns32kum |
7'b10_0x1x_0 : acc_step = acc_ok; // WRITE Adr. ist not perfect and waits for last packet
|
| 331 |
|
|
7'b10_0100_0 : acc_step = acc_ok; // WRITE Adr. perfect - acc_step after 1. packet
|
| 332 |
9 |
ns32kum |
// fast QWord READ : there would be a 2. acc_step if not ~PACK...
|
| 333 |
|
|
7'b11_1xxx_x : acc_step = acc_ok & ( (qwa_flag & ~io_rdy & ca_hit) ? ~PACKET[3] : PACKET[3] );
|
| 334 |
|
|
7'b11_0x1x_x : acc_step = acc_ok;
|
| 335 |
11 |
ns32kum |
7'b11_0100_x : acc_step = acc_ok; // WRITE Adr. perfect - acc_step after 1. packet if not io_acc
|
| 336 |
9 |
ns32kum |
default : acc_step = 1'b0;
|
| 337 |
|
|
endcase
|
| 338 |
|
|
|
| 339 |
|
|
// There is a 2. acc_step if packet (10) - this must be suppressed
|
| 340 |
|
|
always @(posedge BCLK or negedge BRESET)
|
| 341 |
|
|
if (!BRESET) no_done <= 1'b0;
|
| 342 |
|
|
else no_done <= (~acc_ende & acc_step) | (no_done & ~(acc_run & acc_ende));
|
| 343 |
|
|
|
| 344 |
|
|
// The final DONE Multiplexer
|
| 345 |
|
|
assign ACC_DONE = acc_run ? (acc_step & ~no_done) : ea_ok;
|
| 346 |
|
|
|
| 347 |
12 |
ns32kum |
// Bugfix of 7.October 2015
|
| 348 |
|
|
always @(posedge BCLK) QWATWO <= acc_run & acc_ok & qwa_flag & ~io_rdy & ca_hit & ~PACKET[3] & (SIZE == 2'b11) & READ_OUT & ~no_done;
|
| 349 |
|
|
|
| 350 |
29 |
ns32kum |
always @(posedge BCLK) reg_out_i <= ~acc_step & BRESET & ((qwa_flag & ~io_rdy & ~ca_hit & acc_ok) | reg_out_i);
|
| 351 |
9 |
ns32kum |
|
| 352 |
29 |
ns32kum |
always @(posedge BCLK) irdy_flag <= (READ_OUT & io_acc) | (irdy_flag & ~IO_READY); // new 25.6.2018
|
| 353 |
|
|
always @(posedge BCLK) io_rdy <= IO_READY & irdy_flag;
|
| 354 |
9 |
ns32kum |
|
| 355 |
29 |
ns32kum |
always @(posedge BCLK) next_reg <= acc_step & (qwa_flag ? io_rdy : 1'b1) & (SIZE == 2'b11);
|
| 356 |
|
|
assign CTRL_QW = {qwa_flag,(reg_out_i | next_reg)};
|
| 357 |
9 |
ns32kum |
|
| 358 |
|
|
endmodule
|