2013-10-29 3 views
3

Vec [Mem]에게 set-associative cache가 좋을 것 같습니다.Vec [Mem] in Chisel을 가지고있는 것이 좋을 것입니다.

불행하게도 시추 지원하지 않습니다 VEC [의 Mem] 구조 : 실제로

val tag_ram2 = Vec.fill(num_ways) {Mem(new TagType(), num_sets , seqRead = true)} 

:

inferred type arguments [Chisel.Mem[cache.TagType]] do not conform to method fill's type  parameter bounds [T <: Chisel.Data] 
[error] Error occurred in an application involving default arguments. 
[error]  val tag_ram2 = Vec.fill(num_ways) {Mem(new TagType(), num_sets , seqRead = true)} 
[error]        ^
[error] /home/asamoilov/work/projects/my-chisel/Cache.scala:139: type mismatch; 
[error] found : Chisel.Mem[cache.TagType] 
[error] required: T 
[error] Error occurred in an application involving default arguments. 
[error]  val tag_ram2 = Vec.fill(num_ways) {Mem(new TagType(), num_sets , seqRead = true)} 

그러나 간단한 해결 방법은 잘 작동 :

val tag_ram2 = Array.fill(num_ways) {Mem(new TagType(), num_sets , seqRead = true)} 
[...] 
    is (read_tag) { 

     set_idx := req_idx % UInt(num_sets) // FIXME 
     for (way_no <- 0 until num_ways) { 
      tag_read_vec(way_no) := tag_ram2(way_no)(set_idx) 
     } 
     controller_state := compare_tag 
    } 

그리고, 쓰기위한 태그 (일부 경우 (...) 절의 원인)

  for (way_no <- 0 until num_ways) { 
       when (UInt(way_no) === way_idx) { 
        printf("writing to way %d set %d tag %x\n", way_idx, set_idx, tag_write.toBits) 
        tag_ram2(way_no)(set_idx) := tag_write 
       } 
      } 

제안 사항을 개선하기위한 제안? 감사합니다.

+0

기능 요청은 (https://github.com/ucb-bar/chisel/issues) 또는 https://groups.google.com/forum/#에서 볼 수 있고 응답 할 확률이 더 높습니다. ! forum/chisel-users). 내가하는 일은 for 루프를 설정하고 익명으로 for 루프 내에서 각 은행을 정의하는 것입니다. 메모리 뱅킹의 경우 실제로 2 차원 배열을 사용하려고 시도하는 것보다 완벽하게 괜찮은 (어쩌면 더 나은) 것으로 나타났습니다. – Chris

+0

당신은 꽤 옳습니다. 이것은 효과적으로 n_ways X n_sets 태그와 데이터를 유지하기위한 2 차원 배열입니다. 메모리 뱅킹 구현을 살펴볼 수 있습니까? 나는 치즐을 처음 사용하고 최고의 끌의 스타일 가이드를 찾고 있습니다. 감사! –

+1

좋아, github에 코드에서 2 뱅크 메모리 구현을 찾았습니다. https://github.com/ucb-bar/riscv-sodor/blob/master/src/rv32_3stage/memory.scala –

답변

1

태그 배열의 경우 너비가 (n_tag_sz * n_ways) 인 1 차원 비트의 벡터를 사용해보십시오. 캐시 액세스에서 어쨌든 전체 행을 읽었을 때 가능한 한 고밀도로 저장하려고합니다. 그래서 다음과 같이 : 여기

val tag_array = Mem(Bits(width = tagbits*n_ways), n_sets, seqRead = true) 

그리고 ifgen, ic_access 및 ic_response 3주기 (S0, S1, S2) 다루는 I-캐시의 메모리 뱅크에 대한 사이비 코드의 조각은,이다 :

val s1_tag_match = Vec.fill(n_ways){Bool()} 
val s2_tag_hit = Vec.fill(n_ways){Bool()} 
val s2_dout = Vec.fill(n_ways){Reg(Bits())} 

for (i <- 0 until n_ways) 
{ 
    // notice each cycle of refill gets its own line 
    val data_array = Mem(Bits(width = n_code_width), n_sets*REFILL_CYCLES, seqRead = true) 
    val s1_raddr = Reg(UInt()) 
    // refill 
    when (io.mem.resp.valid && repl_way === UInt(i)) 
    { 
     data_array(Cat(s2_idx,rf_cnt)) := io.mem.resp.bits.data 
    } 
    // read enable 
    .elsewhen (s0_valid) 
    { 
     s1_raddr := s0_raddr 
    } 

    // read 
    when (s1_valid && s1_tag_match(i) && ready) 
    { 
     s2_dout(i) := data_array(s1_raddr) 
    } 
} 

io.resp.bits.data := Mux1H(s2_tag_hit, s2_dout) 
+0

고마워요! –