Giter Club home page Giter Club logo

chisel2-deprecated's Introduction

NOTE: This README.md describes (and associated repository contains) version 2.x of Chisel, and while we continue to support this version of Chisel, we encourage people to migrate to the new version: Chisel3

We've removed the Getting Started section of this document. If you're just getting started, you should be using Chisel3.

About Chisel

Chisel is a new open-source hardware construction language developed at UC Berkeley that supports advanced hardware design using highly parameterized generators and layered domain-specific hardware languages.

Chisel is embedded in the Scala programming language, which raises the level of hardware design abstraction by providing concepts including object orientation, functional programming, parameterized types, and type inference.

Visit the community website for more information.

Documentation

Documentation has been moved to a separate repository.

Chisel3

We're releasing snapshot versions of Chisel3. To facilitate the transition from Chisel2, you should ensure that your designs build and test in Chisel3 compatibility mode by passing the following arguments to Chisel:

--minimumCompatibility 3.0.0

If you invoke chiselMain() or chiselMainTest() directly, you should add these arguments to your current argument list:

object hello {
  def main(args: Array[String]): Unit = {
    chiselMainTest(Array[String]("--backend", "c", "--compile", "--test", "--genHarness", "--minimumCompatibility", "3.0.0"),
       () => Module(new HelloModule())){c => new HelloModuleTests(c)}
  }
}

This will report errors for the following Chisel3 issues:

  • Vec(Reg) should be replaced with Reg(Vec),
  • type-only vals (no associated data) must be wrapped in a Wire() if they will be the destination of a wiring operation (":=" or " < >"),
  • masked bit patterns ('b??') should be created using BitPat(), not UInt() or Bits(),
  • the "clone" method required for parameterized Bundles has been renamed "cloneType",
  • the con and alt inputs to a Mux must be type-compatible - both signed or both unsigned,
  • bulk-connection to a node that has been procedurally assigned-to is illegal,
  • != is deprecated, use =/= instead,
  • use SeqMem(...) instead of Mem(..., seqRead),
  • use SeqMem(n:Int, out: => T) instead of SeqMem(out: => T, n:Int),
  • use Mem(n:Int, t:T) instead of Mem(out:T, n:Int),
  • use Vec(n:Int, gen: => T) instead of Vec(gen: => T, n:Int),
  • Mem(..., orderedWrites) is no longer supported,
  • masked writes are only supported for Mem[Vec[_]],
  • connections between UInt and SInt are illegal.
  • module io's must be wrapped in IO().

In addition, the following incompatibilities require code changes:

  • the Node class and object no longer exist (the class should have been private in Chisel2)
  • printf() is defined in the Chisel object and produces simulation printf()'s. To use the Scala Predef.printf(), you need to qualify it with Predef.
  • in Chisel2, bulk-connects <> with unconnected source components do not update connections from the unconnected components. In Chisel3, bulk-connects strictly adhere to last connection semantics and unconnected OUTPUTs will be connected to INPUTs resulting in the assignment of random values to those inputs.

chisel2-deprecated's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

chisel2-deprecated's Issues

List lookup width broken

On Behalf of Chris:

I'm pretty sure this worked for me on the C++ backend, but not on the Verilog backend.

I'm using list lookup and it gets the "rrd_op_fcn" size wrong:

val FN_X    = Bits(0 )
val FN_ADD  = Bits(0 )
val FN_SL   = Bits(1 )
val FN_XOR  = Bits(4 )
val FN_OR   = Bits(6 )
val FN_AND  = Bits(7 )
val FN_SR   = Bits(5 )
val FN_SUB  = Bits(8 )
val FN_SLT  = Bits(10)
val FN_SLTU = Bits(11)
val FN_SRA  = Bits(13)
val FN_OP2  = Bits(15)
val FN_OP1  = Bits(14)

val rrd_csignals =        ListLookup(io.rrd_uop.uopc,
                          List(BR_N , Y, N, N, FN_ADD , DW_X  , OP2_RS2, REN_0, WB_X  , PCR.N),
           Array(
              uopNOP   -> List(BR_N , Y, N, N, FN_ADD , DW_XPR, OP2_RS2, REN_0, WB_X  , PCR.N),
              uopLD    -> List(BR_N , N, N, Y, FN_ADD , DW_XPR, OP2_IMM, REN_0, WB_X  , PCR.N),
              uopMFPCR -> List(BR_N , Y, N, N, FN_OP2 , DW_XPR, OP2_X  , REN_1, WB_PCR, PCR.F),
              uopRDC   -> List(BR_N , Y, N, N, FN_OP2 , DW_XPR, OP2_TSC, REN_1, WB_ALU, PCR.N),
              uopRDI   -> List(BR_N , Y, N, N, FN_OP2 , DW_XPR, OP2_IRT, REN_1, WB_ALU, PCR.N)
              )); 

val rrd_br_type :: rrd_use_alupipe :: rrd_use_muldivpipe :: rrd_use_mempipe :: rrd_op_fcn :: rrd_fcn_dw :: rrd_op2_sel :: rrd_rf_wen :: rrd_wb_sel :: rrd_pcr_fcn :: Nil = rrd_csignals;

  println("width of fn_add: " + FN_ADD.getWidth)   // size 1
  println("width of fn_op2: " + FN_OP2.getWidth)  // size 4
  println("width of rrd_op_fcn: " + rrd_op_fcn.getWidth) // size 1, this should be size 4

Listlookup needs to use figure out the worst case width of each line.

More out-of-the-box Verilog examples

It seems that neither the Chisel tutorial circuits nor Sodor (the two examples linked on the Chisel homepage) are configured to generate Verilog out-of-the-box. To the extent that we are trying to convince hardware designers to use Chisel, the following conversation ends poorly:

Us: Chisel is great!
Hardware dev: OK, I'd like to try it out in my FPGA/ASIC toolchain. Can you provide an example hardware block that generates Verilog?
Us: Well, you'll have to modify the build scripts to generate the Verilog backend…

Perhaps the examples that we already provide could be modified to include these additional targets.

no enable default for mem enable in verilog backend

In my design, I didn't need a read enable, as I was reading on every cycle. The code looked like:

val ram1rw = Mem(Bits(width=64), 64, seqRead=true)
val ram_raddr = Reg(next=io.addr)

It turns out that while the Chisel tests pass, the synthesized verilog is wrong. It tries to use an arbitrary term as the read enable for the SRAM macro (in my case a 64 bit term). This can be solved by changing the chisel to the following:

val ram1rw = Mem(Bits(width=64), 64, seqRead=true)
val ram_raddr = Reg(Bits())
when (Bool(true)) { ram_raddr := io.addr }

Which correctly ties a true value to the read enable.

VHDL Back End

If I am not mistaken the current targeting is Verilog? In which case perhaps you can support VHDL also.

printf being discarded during elaboration

Chisel printf constructs are discarded during elaboration unless the enclosing module contains synchronous sequential logic.

The following minimal example produces Verilog lacking a corresponding $fwrite command.

class Example1 extends Module {
    val io = new Bundle {
        val in = Bool(INPUT)
    }
    printf("%b\n", io.in)
}
module Example1(input reset,
    input  io_in
);

  wire[15:0] T0;
  wire T1;
  wire T2;

  assign T1 = ! reset;
  assign T2 = io_in;
endmodule

Adding an Updateable node fixes the issue.

class Example2 extends Module {
    val io = new Bundle {
        val in = Bool(INPUT)
        val out = Bool(OUTPUT)
    }
    val r = Reg(next = io.in)
    io.out := r
    printf("%b\n", io.in)
}
module Example2(input clk, input reset,
    input  io_in,
    output io_out
);

  wire T0;
  wire[15:0] T1;
  wire T2;
  reg[0:0] r;

  assign T0 = ! reset;
  assign T2 = io_in;
  assign io_out = r;

  always @(posedge clk) begin
`ifndef SYNTHESIS
`ifdef PRINTF_COND
    if (`PRINTF_COND)
`endif
      if (T0)
        $fwrite(32'h80000002, "%b\n", T2);
`endif    r <= io_in;
  end
endmodule

Website stackoverflow link doesn't work

This is pretty minor, but, there's a link to stackoverflow with the chisel tag. But, you can't actually ask a chisel question (unless you have 1500 rep), because there's no existing chisel tag, and you need 1500 rep to create a tag.

In case it matters, this github issue was inspired by an actual question

Queue is generating incorrect code; io.deq signals don't match io.enq signals.

==PROBLEM==

The Queue in ChiselUtil is generating incorrect code - the Queue's internal RAM's width does not match the io.enq width. This is causing it to extract the wrong signals, as now the outbound io.deq signals don't match the incoming io.enq signals.

==SYMPTOM==

Code compiles in both C++ and Verilog but returns the wrong answer. The values of the io.deq signals do not match the incoming io.enq signals. The values of signals has been shifted over by two.

==CAUSE==

An ambiguous width signal in the Bundle being used as the "gen" type for the Queue.

==SUSPECTED PROBLEM==

I suspect that one of the fields has a width of "-1", which is screwing up the math of the extract code. In particular, the Verilog says:

assign T29 = T14[1'h1/* -1*/:1'h1/* -1*/];

It looks like it is literally trying to extract Bits T14[-1:-1], and by dumb luck extracting [1:1] properly. But the next field in the Bundle is reset to extract from [0:0], causing a shift in the extract logic and causing the fields in the higher order bits of T14 to be pulled out incorrectly.

This bug may actually reside in Mem.

==MORE INFO==

I have a Bundle() which is passed into the Queue as the "gen" type. I added a new field to the bundle with an undefined width (btb_pred_taken_idx = UInt()):

class FetchBundle(implicit conf: BOOMConfiguration)  extends Bundle            
{                                                                              
   val fetch_width = conf.icache.ibytes/4                                      

   val pc    = UInt(width = XPRLEN)                                            
   val insts = Vec.fill(fetch_width) { Bits(width = 32) }                      
   val mask  = Bits(width = fetch_width) // mark which words are val

   val br_predictions = Vec.fill(fetch_width) { new BrPrediction }  // 3 bits in width
   val btb_pred_taken = Bool()                                                 
   val btb_pred_taken_idx = UInt() // << --- THIS IS BREAKING THINGS

  override def clone = new FetchBundle().asInstanceOf[this.type]               
}                                                                              

 val fetch_bundle = new FetchBundle()                                               

 val FetchBuffer = Module(new Queue(gen=new FetchBundle,                            
                             entries=FETCH_BUFFER_SZ,
                             pipe=false,                                           
                             flow=ENABLE_FETCH_BUFFER_FLOW_THROUGH,
                             _reset=(fetchbuffer_kill || reset.toBool)))           

The bug is that io.enq.bits.pc does not match io.deq.bits.pc!

The FetchBuffer is a 102-bit wide bundle (for a fetch_width of 1) stored in variable T21; however, it generates an underlying RAM of 100 bits in size.

The PC is stored in bits [101:37] of the aggregated bundle T21. The Queue module pulls out bits [99:36] for io.deq.bits.pc. :( :( :(

Generated Verilog Code

 module Queue_0(input clk, input reset,
     output io_enq_ready,
     input  io_enq_valid,
     input [63:0] io_enq_bits_pc,
     input [31:0] io_enq_bits_insts_0,
     input  io_enq_bits_mask,
     input  io_enq_bits_br_predictions_0_taken,
     input  io_enq_bits_br_predictions_0_agreement,
     input  io_enq_bits_br_predictions_0_local_taken,
     input  io_enq_bits_btb_pred_taken,
     input  io_enq_bits_btb_pred_taken_idx,
     input  io_deq_ready,
     output io_deq_valid,
     output[63:0] io_deq_bits_pc,
     output[31:0] io_deq_bits_insts_0,
     output io_deq_bits_mask,
     output io_deq_bits_br_predictions_0_taken,
     output io_deq_bits_br_predictions_0_agreement,
     output io_deq_bits_br_predictions_0_local_taken,
     output io_deq_bits_btb_pred_taken,
     output io_deq_bits_btb_pred_taken_idx,
     output[2:0] io_count
 );

   <snip>

   wire ptr_match;
   reg[1:0] enq_ptr;
   wire[1:0] T7;
   wire[1:0] T8;
   wire T9;
   wire[1:0] T10;
   wire[1:0] T11;
   wire T12;
   wire T13;
   wire[101:0] T14;
   wire[101:0] T15;
   wire T16;
   wire[99:0] T17;
   reg [99:0] ram [3:0];
   wire[99:0] T18;
   wire[99:0] T19;
   wire[101:0] T20;
   wire[101:0] T21;
   wire T22;
   wire T23;
   wire T24;
   wire T25;
   wire T26;
   wire[31:0] T27;
   wire[63:0] T28;

   <snip> 

   assign io_deq_bits_btb_pred_taken_idx = T13;
   assign T13 = T14[1'h0/* 0*/:1'h0/* 0*/];
   assign T14 = maybe_flow ? T21 : T15;
   assign T15 = {T28, T27, T26, T25, T24, T23, T22, T16};
   assign T16 = T17[1'h0/* 0*/:1'h0/* 0*/];
   assign T17 = ram[deq_ptr];
   assign T19 = T20[7'h63/* 99*/:1'h0/* 0*/];
   assign T20 = T21;
   assign T21 = {io_enq_bits_pc, io_enq_bits_insts_0, io_enq_bits_mask, io_enq_bits_br_predictions_0_taken, io_enq_bits_br_predictions_0_agreement, io_enq_bits_br_predictions_0_local_taken, io_enq_bits_btb_pred_taken, io_enq_bits_btb_pred_taken_idx};
   assign T22 = T17[1'h1/* -1*/:1'h1/* -1*/];
   assign T23 = T17[1'h0/* 0*/:1'h0/* 0*/];
   assign T24 = T17[1'h1/* 1*/:1'h1/* 1*/];
   assign T25 = T17[2'h2/* 2*/:2'h2/* 2*/];
   assign T26 = T17[2'h3/* 3*/:2'h3/* 3*/];
   assign T27 = T17[6'h23/* 35*/:3'h4/* 4*/];
   assign T28 = T17[7'h63/* 99*/:6'h24/* 36*/];
   assign io_deq_bits_btb_pred_taken = T29;
   assign T29 = T14[1'h1/* -1*/:1'h1/* -1*/];
   assign io_deq_bits_br_predictions_0_local_taken = T30;
   assign T30 = T14[1'h0/* 0*/:1'h0/* 0*/];
   assign io_deq_bits_br_predictions_0_agreement = T31;
   assign T31 = T14[1'h1/* 1*/:1'h1/* 1*/];
   assign io_deq_bits_br_predictions_0_taken = T32;
   assign T32 = T14[2'h2/* 2*/:2'h2/* 2*/];
   assign io_deq_bits_mask = T33;
   assign T33 = T14[2'h3/* 3*/:2'h3/* 3*/];
   assign io_deq_bits_insts_0 = T34;
   assign T34 = T14[6'h23/* 35*/:3'h4/* 4*/];
   assign io_deq_bits_pc = T35;
   assign T35 = T14[7'h63/* 99*/:6'h24/* 36*/];
   assign io_deq_valid = T36;
   assign T36 = T37 || io_enq_valid;
   assign T37 = ! maybe_flow;
   assign io_enq_ready = T38;
   assign T38 = ! full;
   assign full = ptr_match && maybe_full;


   always @(posedge clk) begin
     if(reset) begin
       deq_ptr <= 2'h0/* 0*/;
     end else if(do_deq) begin
       deq_ptr <= T10;
     end
     if(reset) begin
       maybe_full <= 1'h0/* 0*/;
     end else if(T4) begin
       maybe_full <= do_enq;
     end
     if(reset) begin
       enq_ptr <= 2'h0/* 0*/;
     end else if(do_enq) begin
       enq_ptr <= T7;
     end
     if (do_enq)
       ram[enq_ptr] <= T19;
   end
 endmodule

// if you've made it this far, here's a joke for your time:
// A SQL query goes into a bar, walks up to two tables and asks, "Can I join you?"

From the above code, we can discern the following:

  • the Incoming io.enq signals are placed into T21, which is properly 102 bits in size.
  • T21 is improperly shortened to 100-bits and placed into "ram".
  • ram is placed into T17, from which the individual io.deq.bits fields are extracted from
  • the first field (btb_pred_taken_idx), our hero of unspecified width (should be 1-bit in size), is extracted from T17[0:0] and into T16.
  • The second field (btb_pred_taken), is extracted from T17[-1:-1]. Ruh-roh Shaggie!
  • The third field (br_predictions_0_local_taken) is extracted from T17[0:0]… the same as btb_pred_taken_idx!
  • The extracting of the remaining fields continues, but now offset by 2.

==WORKAROUND==

Specify the width of UInt() btb_pred_taken_idx. Continue to curse the width inference code.

Thank you for reading. I'd fix this myself, but I can't make heads or tails of the subtly different meanings of width, getWidth, inferWidth, WidthOf(),fixWidth(), matchWidth(), and friends.

Give warning when addressing outside of memory in C++ and prevent reads/writes outside the memory.

There is a particular nasty bug if your memory is not a power of two, and you give access an address outside of that range in C++. It would be incredibly useful if there was a runtime warning the first time a read or write is made to an address outside of the memory in C++. After the first time, it should be silent as the value may in fact never be used.

Currently, mem_t will access outside of the array causing strange output without any apparent cause. It would be good to prevent the mem_t array from writing outside the bounds of the array as this may cause unrelated parts of the program to exhibit weird behavior. This also helps to prevent weird behavior if the user forgets to reduce the address to be within the depth (even if the memory is a power of two).

run ... --compile --test hangs even though design compiles without errors

This is probably some user error on my part, but the design compiles with NO COMBINATIONAL LOOP FOUND, so it's at least not the most obvious thing that might cause a simulation to hang.

This is the Mux2 example from the chisel tutorial with a constant output added. Apparently, this is a bad way to do that, and it causes the test to run forever.

To be concrete, it would be nice if it was possible to add an error message to catch whatever I'm doing to cause this problem.

package TutorialSolutions

import Chisel._
import scala.math._
import scala.collection.mutable.HashMap

class Mux2 extends Module {
  val io = new Bundle {
    val sel = Bits(INPUT,  1)
    val in0 = Bits(INPUT,  1)
    val in1 = Bits(INPUT,  1)
    val out = Bits(OUTPUT, 1)
    val const = Bits(OUTPUT, 1)
  }
  io.out := (io.sel & io.in1) | (~io.sel & io.in0)
  io.const := Bits(0)
}

class Mux2Tests(c: Mux2) extends Tester(c, Array(c.io)) {
  defTests {
    var allGood = true
    val n = pow(2, 3).toInt
    val vars = new HashMap[Node, Node]()
    for (s <- 0 until 2) {
      for (i0 <- 0 until 2) {
        for (i1 <- 0 until 2) {
          vars(c.io.sel) = Bits(s)
          vars(c.io.in1) = Bits(i1)
          vars(c.io.in0) = Bits(i0)
          vars(c.io.const) = Bits(0)
          vars(c.io.out) = Bits(if (s == 1) i1 else i0)
          allGood = step(vars) && allGood
        }
      }
    }
    allGood
  }
}

Out of bound ROM access(C++) produces no warning or error

Accessing a ROM dynamically out of bounds at runtime produces undefined behavior, instead of a warning or error.
The result is the functionality of a module changes after each compilation with no errors or warnings from chisel.

Suggestion: Either add a warning or error at runtime perhaps only emit the runtime checks if --debug flag is there

Chisel Connection Warnings output file

On Behalf of James:

It used to be that the older Chisel would generate a verbose warning file of all connections that were unconnected. However, it v1.1 this has been removed, and when "-Wall" is set, not all of the unconnected inputs or outputs are being listed.

Having a verbose printout of everything that is unconnected is very useful. I (and I am sure others) would welcome the return of this warning output.

no updates on reg fails to print reg name

when i have a reg declared at top level and fail to specify updates on it i get an error message without the reg's name:

flo.scala:171: error: NO UPDATES ON REG(REG) in class Flo.Compute

here is the reg in question defined at top level:

val numStrands = Reg(init = UInt(0, width = log2Up(NUM_STRANDS)))

IO names changed when using assigning to a variable

class myComp extends Component {
    val io = new Bundle {  
        val in = Bits(INPUT, 20)
        val out = Bits(OUTPUT, 20)
    }   

    val newName = io.in

    io.out := newName
}

Causes the IO name to be changed in both the elaborated C++ and Verilog.

Above will generate this for Verilog:

module myComp(
     input [19:0] newName,
     output[19:0] io_out);


   assign io_out = newName;
 endmodule

I/O names should remain constant regardless if they are assigned to another variable in the Component.

Correct output is below:

module myComp(
     input [19:0] io_in,
     output[19:0] io_out);


   assign io_out = io_in;
 endmodule

Bug with Incremental Compile of Submodules

We are taping out with the reference chip and we've noticed a new Chisel bug that's cropped up recently. I'm not certain it's to do with the new Chisel version but it might be related.

We frequently recompile the reference chip after making changes to submodule code. Chisel will often throw an error:

cd /scratch/bkeller/raven3-chip/sbt && java -Xmx2048M -Xss8M -XX:MaxPermSize=128M -jar sbt-launch.jar "project referencechip" "elaborate Top --backend referencechip.ReferenceChipBackend --targetDir /scratch/bkeller/raven3-chip/vlsi/build/generated-src --noInlineMem"
[info] Loading project definition from /scratch/bkeller/raven3-chip/sbt/project
[info] Set current project to sbt (in build file:/scratch/bkeller/raven3-chip/sbt/)
[info] Set current project to referencechip (in build file:/scratch/bkeller/raven3-chip/sbt/)
[info] Compiling 1 Scala source to /scratch/bkeller/raven3-chip/sbt/rocket/target/scala-2.10/classes...
[warn] there were 41 feature warning(s); re-run with -feature for details
[warn] one warning found
java.lang.IllegalArgumentException: requirement failed: Source file '/scratch/bkeller/raven3-chip/sbt/rocket/target/scala-2.10/classes/rocket/HTIFIO.class' does not exist.
at scala.Predef$.require(Predef.scala:233)
at sbt.IO$.copyFile(IO.scala:549)
at sbt.IO$.move(IO.scala:690)
at sbt.inc.ClassfileManager$$anonfun$transactional$1$$anon$2.sbt$inc$ClassfileManager$$anonfun$$anon$$move(ClassfileManager.scala:61)
at sbt.inc.ClassfileManager$$anonfun$transactional$1$$anon$2$$anonfun$delete$1.apply(ClassfileManager.scala:45)
at sbt.inc.ClassfileManager$$anonfun$transactional$1$$anon$2$$anonfun$delete$1.apply(ClassfileManager.scala:44)
at scala.collection.immutable.HashSet$HashSet1.foreach(HashSet.scala:153)
at scala.collection.immutable.HashSet$HashTrieSet.foreach(HashSet.scala:306)
at scala.collection.immutable.HashSet$HashTrieSet.foreach(HashSet.scala:306)
at sbt.inc.ClassfileManager$$anonfun$transactional$1$$anon$2.delete(ClassfileManager.scala:44)
at sbt.inc.Incremental$.prune(Incremental.scala:294)
at sbt.inc.Incremental$.cycle(Incremental.scala:70)
at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:33)
at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:32)
error java.lang.IllegalArgumentException: requirement failed: Source file '/scratch/bkeller/raven3-chip/sbt/rocket/target/scala-2.10/classes/rocket/HTIFIO.class' does not exist.
[error] Total time: 13 s, completed Aug 27, 2013 11:24:08 PMf

And we need to manually delete the target directories to get it to rebuild.

Verilog Backend ListLookup Infer Width Is Broken

I'm using a ListLookup to set control signals. But it's using the wrong width for a signal with an implicit width.

object ALU
{
   val FN_X    = Bits(0)
   val FN_ADD  = Bits(0)
   val FN_SL   = Bits(1)
   val FN_XOR  = Bits(4 )
   val FN_OR   = Bits(6 )
   val FN_AND  = Bits(7 )
   val FN_SR   = Bits(5 )
   val FN_SUB  = Bits(8 )
   val FN_SLT  = Bits(10)
   val FN_SLTU = Bits(11)
   val FN_SRA  = Bits(13)
   val FN_OP2  = Bits(15)
   val FN_OP1  = Bits(14)
}
import ALU._

 val rrd_csignals =
    ListLookup(io.rrd_uop.uopc,
                    List(BR_N , FN_ADD , DW_X  ),
      Array(                    
        uopNOP   -> List(BR_N , FN_ADD , DW_XPR),
        uopLD    -> List(BR_N , FN_ADD , DW_XPR),
        uopSTA   -> List(BR_N , FN_OP2 , DW_XPR),
        uopSTD   -> List(BR_N , FN_X   , DW_X  )
        ))
    val rrd_br_type :: rrd_op_fcn :: rrd_fcn_dw :: Nil = rrd_csignals;

The issue is that FN_ADD is 1b wide, but FN_OP2 is 4b wide. When extracting out the control signal to "rrd_op_fcn", ListLookup needs to realize that "rrd_op_fcn" needs to be the max size of the wire it found in the ListLookup.

This works in C++, but is broken in Verilog.

More Code

 val io = new Bundle
 {
    val iss_valid = Bool(INPUT)
    val iss_uop   = new MicroOp().asInput()
    val rrd_valid = Bool(OUTPUT)
    val rrd_uop   = new MicroOp().asOutput()
 }
 // Issued Instruction
 val rrd_valid = io.iss_valid
 io.rrd_uop   := io.iss_uop

 val rrd_csignals =
    ListLookup(io.rrd_uop.uopc,
                    List(BR_N , FN_ADD , DW_X  ),
      Array(                    
        uopNOP   -> List(BR_N , FN_ADD , DW_XPR),
        uopLD    -> List(BR_N , FN_ADD , DW_XPR),
        uopSTA   -> List(BR_N , FN_OP2 , DW_XPR),
        uopSTD   -> List(BR_N , FN_X   , DW_X  )
        ))

 val rrd_br_type :: rrd_op_fcn :: rrd_fcn_dw :: Nil = rrd_csignals;

 println("width of fn_add: " + FN_ADD.getWidth) // returns 1
 println("width of fn_op2: " + FN_OP2.getWidth) // returns 4
 println("width of rrd_op_fcn: " + rrd_op_fcn.getWidth) // returns 1 SAD PANDA

 io.rrd_uop.ctrl.op_fcn  := rrd_op_fcn.toBits

The Verilog

 module RegisterReadDecode(                      
     input  rrd_valid,                           
     input  io_iss_uop_valid,                    
      <snip>
     input [3:0] io_iss_uop_ctrl_op_fcn,         
     output[3:0] io_rrd_uop_ctrl_op_fcn,  
     <snip>
reg[0:0] rrd_op_fcn;    
  always @(*) begin
    casez (io_rrd_uop_uopc)
      9'h0/* 0*/ : begin
        rrd_br_type = 4'h0/* 0*/;
        rrd_op_fcn = 1'h0/* 0*/;
        rrd_fcn_dw = 1'h1/* 1*/;
      end
      9'h1/* 1*/ : begin
        rrd_br_type = 4'h0/* 0*/;
        rrd_op_fcn = 1'h0/* 0*/;

        // Q: Why do programmers always mix up Halloween and Christmas?

        // A: Because Oct 31 == Dec 25!

chisel printf is unordered

Entered as an issue on behalf of Chris:

So i'm trying out the Chisel printf, which is frankly a must-have as I go forward with debugging a parameterized core in Verilog (where I have no printf code written up yet in the Verilog testharness)...

I have code like this in my Chisel:

// print out ROB
for (i <- 0 until num_rob_entries)
{
printf(" rob[%d] %d %d (PC:0x%x) 0x%x\n"
, UFix(i)
, rob.io.debug.entry(i).valid
, rob.io.debug.entry(i).busy
, rob.io.debug.entry(i).uop.pc
, rob.io.debug.entry(i).uop.inst
)
}

Unfortunately, the order is all jumbled (notice the numbers in the brackets):

rob[5] 0 0 (PC:0xe0cc2cc10d53011a) 0x19ba8133
rob[2] 0 0 (PC:0xad9afe5b3d25cd7a) 0x5d437fba
rob[7] 0 0 (PC:0x1dee813b0abfc715) 0x6f15c9de
rob[3] 0 0 (PC:0x99489c3289202a12) 0x522a21a4
rob[14] 0 0 (PC:0x213d974256d1f3ad) 0xd663a4ac
rob[4] 0 0 (PC:0xc7bec28f2ec5515d) 0x835e7206
rob[6] 0 0 (PC:0x3672316cc78d408f) 0x13c85527
etc….

It is also unordered relative to any printfs/$displays in the test harness itself.

In short, I can't make use of Chisel printfs (outside of perhaps catching on-off error conditions, but I should just use Assert for that anyways).

Staged Optimisation

Ability to optimise design through staging where the components are reduced for space, speed, etc. constraint by factors like interference, material properties, etc.

IOException and Message: Stream Closed during simulation

I had some occasional test failures, so started running my tests repeatedly in a loop in the hope that the randomized testing would eventually flush out bugs in my design. However, it seem the occasional failures might be caused by not getting pipe to the simulation, or the simulation failing, I'm not sure.

I get an IOException during the call to step() with Message: Stream Closed.

Occasional flakiness in getting the simulation up and running and IPC with it working, needs some investigation into making it more robust. Occasional test failures caused by this are giving a false flag, which might be misleading as occasional test failures would indicate some hard to find bugs are occasionally being hit by the tests.

Prune unconnected I/Os

I would like Chisel to:

  • have some notion of "unconnected I/O"
  • the ability to remove unconnected outputs
  • the ability to discern if an unconnected input is an error (because a connected output depends on it), and remove if not an error.
  • proper Chisel code should generate correct Verilog with no warnings

What's really unsettling about all of this is that we can run into inconsistencies between C++ simulation and Verilog simulation and Verilog synthesis. In C++ an unhooked up I/O I think just becomes a zero (or is that the decision of the compiler?). In Verilog it becomes 1'hz.

Need to add a flush on the dump() when generating VCD

Hi,

If the --vcd option is used, often I am finding that the .vcd file does not seem to contain the full trace of a test run.

I think a call to fflush() is needed at the end of the dump() function to ensure the file is written?

Emulator broken

Running 'make emulator' works but 'make emulator-debug' doesn't.

The error I get is:
generated-src-debug/Top.cpp: In member function ‘virtual void Top_t::dump(FILE_, int)’:
generated-src-debug/Top.cpp:1526:47: error: ‘Top_hio_tohost_q__do_flow__prev’ was not declared in this scope
if (t == 0 || (Top_hio_tohost_q__do_flow != Top_hio_tohost_q__do_flow__prev).to_bool())
^
generated-src-debug/Top.cpp:1528:3: error: ‘Top_hio_tohost_q__do_flow__prev’ was not declared in this scope
Top_hio_tohost_q__do_flow__prev = Top_hio_tohost_q__do_flow;
^
generated-src-debug/Top.cpp:1607:49: error: ‘Top_hio_fromhost_q__do_flow__prev’ was not declared in this scope
if (t == 0 || (Top_hio_fromhost_q__do_flow != Top_hio_fromhost_q__do_flow__prev).to_bool())
^
generated-src-debug/Top.cpp:1609:3: error: ‘Top_hio_fromhost_q__do_flow__prev’ was not declared in this scope
Top_hio_fromhost_q__do_flow__prev = Top_hio_fromhost_q__do_flow;
^
generated-src-debug/Top.cpp:1715:46: error: ‘Top_htif_x_init__do_flow__prev’ was not declared in this scope
if (t == 0 || (Top_htif_x_init__do_flow != Top_htif_x_init__do_flow__prev).to_bool())
^
generated-src-debug/Top.cpp:1717:3: error: ‘Top_htif_x_init__do_flow__prev’ was not declared in this scope
Top_htif_x_init__do_flow__prev = Top_htif_x_init__do_flow;
^
generated-src-debug/Top.cpp:1772:43: error: ‘Top_htif__scr_rdata_0__prev’ was not declared in this scope
if (t == 0 || (Top_htif__scr_rdata_0 != Top_htif__scr_rdata_0__prev).to_bool())
^
generated-src-debug/Top.cpp:1774:3: error: ‘Top_htif__scr_rdata_0__prev’ was not declared in this scope
Top_htif__scr_rdata_0__prev = Top_htif__scr_rdata_0;
^
generated-src-debug/Top.cpp:1775:43: error: ‘Top_htif__scr_rdata_1__prev’ was not declared in this scope
if (t == 0 || (Top_htif__scr_rdata_1 != Top_htif__scr_rdata_1__prev).to_bool())
^
generated-src-debug/Top.cpp:1777:3: error: ‘Top_htif__scr_rdata_1__prev’ was not declared in this scope
Top_htif__scr_rdata_1__prev = Top_htif__scr_rdata_1;
^
make: *_* [Top-debug.o] Error 1

I can supply code that produces this if you need it.

"Dotting" into a Module to read out public fields generates broken Verilog code

So this may be a mortal sin, but I'm trying to "dot" into a Module to read some of its public fields (instead of using it's I/O bundle).

The issue is, for debug/printf purposes, I need to read the internal signals of the Queue() from ChiselUtil. Since this isn't my code, but rather ChiselUtil code, I can't widen the I/O interface (I'm not going to create a separate Chisel branch over this).

Here's how I'm using it.

for (i <- 0 until FETCH_BUFFER_SZ)
{
   val entry = FetchBuffer.ram(UInt(i))
   debug_string = sprintf("%s   [PC:0x%x %x %s) %s %d %s] %s %s  \n"
        , debug_string
        , entry.pc(19,0)
        , entry.mask.toBits
        , InstsStr(entry.insts.toBits, FETCH_WIDTH)
        , Mux(entry.btb_pred_taken, Str("B"), Str(" "))
        , entry.btb_pred_taken_idx
        , Mux(entry.br_predictions(0).taken, Str("H"), Str(" "))
        , Mux(FetchBuffer.deq_ptr === UInt(i), Str("H"), Str(" "))
        , Mux(FetchBuffer.enq_ptr === UInt(i), Str("T"), Str(" "))
     )
}

This works beautifully in the C++ backend. This generates uncompilable Verilog code.

Error-[IND] Identifier not declared
/scratch/celio/boom/vlsi/build/generated-src/Top.v, 88511
  Identifier 'io_enq_bits_pc' has not been declared yet. If this error is not 
  expected, please check if you have set `default_nettype to none.


Error-[IND] Identifier not declared
/scratch/celio/boom/vlsi/build/generated-src/Top.v, 88511
  Identifier 'io_enq_bits_insts_0' has not been declared yet. If this error is
  not expected, please check if you have set `default_nettype to none.


Error-[IND] Identifier not declared
/scratch/celio/boom/vlsi/build/generated-src/Top.v, 88511
  Identifier 'io_enq_bits_insts_1' has not been declared yet. If this error is
  not expected, please check if you have set `default_nettype to none.


Error-[IND] Identifier not declared
/scratch/celio/boom/vlsi/build/generated-src/Top.v, 88511
  Identifier 'io_enq_bits_mask' has not been declared yet. If this error is 
  not expected, please check if you have set `default_nettype to none.

etc. 

Give Same Warnings in C++ Elaboration as Verilog Elaboration

Currently, only Verilog elaboration will give you unconnected warnings. It would be great if the C++ elaboration gave the same warnings as Verilog elaboration. Users are probably using the C++ elaborated code first and the Verilog elaborated code last.

Scala / Java Simulator

Using another back end takes time. So for quick and dirty try outs of a design to see basic functionality with hot code reloading for changes while you code like a REPL. Or someway to simulate while you modify code.

Invalid extract goes undetected in a mux. Carryout not included in width calculations.

There were no errors or warnings for attempting to extract the 5th bit from the result of adding two 4 bit signals. It was used in a mux inline.

This source code:


def buildCarryChain(size: Int, r: Bits, p: Bits) : Bits = {
    val grant_pass1 = ~r.toUFix() + p.toUFix();
    val grant_pass2 = ~r.toUFix() + UFix(1, size);
    return Mux(grant_pass1(size).toBool(), r & grant_pass2(size-1, 0), r & grant_pass1(size-1, 0));
}

became this C++ emulator output:


dat_t<4> T771 = ~L2Cache_scheduler_arbiter__io_req;
dat_t<4> T772 = T771 + L2Cache_scheduler_arbiter__prio;
dat_t<1> T773 = T772.bit(LIT<3>(0x4L)/* 4*/);
dat_t<4> T774 = ~L2Cache_scheduler_arbiter__io_req;
dat_t<4> T775 = T774 + LIT<4>(0x1L)/* 1*/;
dat_t<4> T776 = T775.extract<4>(LIT<2>(0x3L)/* 3*/,LIT<1>(0x0L)/* 0*/);
dat_t<4> T777 = L2Cache_scheduler_arbiter__io_req & T776;
dat_t<4> T778 = T772.extract<4>(LIT<2>(0x3L)/* 3*/,LIT<1>(0x0L)/* 0*/);
dat_t<4> T779 = L2Cache_scheduler_arbiter__io_req & T778;
L2Cache_scheduler_arbiter__grant_next = mux<4>(T773, T777, T779);

Notice the line for T773 extracting bit position 4 from a 4-bit signal.

It would also be nice to have the carryout available for addition, but this may require more effort where the extra bit is undesired. Perhaps it is something that could be inferred based on usage.

Chisel's Printf doesn't detect Bundles in place of Bits

I accidentally tried to printout a Bundle (the reg_status value found in the PCR in Rocket and Sodor).

I actually want reg_status.toBits. Unfortunately, Chisel didn't detect a type mismatch and everything simulated without issue. I just got wrong answers out of Chisel's Printf.

print("%x", pcr.io.status) // incorrect, but no compile-time error

print("%x", pcr.io.status.toBits) // correct!

not sure whether input wire value updated correctly being called from def

The testcase below:

import Chisel._

class CannotUpdateWire extends Module
{
    val io = new Bundle {
        val update_state = Bool(INPUT)

        val out1 = UInt(OUTPUT, width = 1)
        val out2 = UInt(OUTPUT, width = 1)
    }

    printf("Hi from inside Wire module io.update_state %b\n", io.update_state)

    when (io.update_state) {
        printf("do update state\n")

        io.out1 := UInt(1)
        io.out2 := UInt(0)

    } .otherwise {
        printf("do something else\n")

        io.out1 := UInt(0)
        io.out2 := UInt(1)
    }
}

class Test extends Module
{
    val io = new Bundle {
        val en = Bool(INPUT)
    }

    val counter = Reg(init = UInt(0, width = 8))

    val inst = Module(new CannotUpdateWire)
    val out1 = UInt(width = 1)
    val out2 = UInt(width = 1)

    inst.io.update_state := Bool(true)
    out1 := UInt(0)
    out2 := UInt(0)

    def test_touch_state = {
        inst.io.update_state := Bool(true)
        out1 := inst.io.out1
        out2 := inst.io.out2
        //printf("test_touch_state is called io.out1 %b io.out2 %b\n", out1, out2)
    }

    def get_victim = {
        inst.io.update_state := Bool(false)
        out1 := inst.io.out1
        out2 := inst.io.out2
        //printf("get_victim is called io.out1 %b io.out2 %b\n", out1, out2)
    }

    printf("counter: %d\n", counter)

    when (counter === UInt(0)) {
        //inst.io.update_state := Bool(true)
        test_touch_state

        counter := counter + UInt(1)
    } .elsewhen (counter === UInt(1)) {
        //inst.io.update_state := Bool(false)
        get_victim

        counter := counter + UInt(1)
    } .elsewhen (counter === UInt(2)) {
        //inst.io.update_state := Bool(true)
        test_touch_state

        counter := counter + UInt(1)
    }
}

object test_driver {
    def main(args: Array[String]): Unit = {
        val cannot_wire_inst = () => Module(new Test)

        chiselMain(args, cannot_wire_inst)
    }
}

after generating C++ backend and simulating it behaves strangely :

./Test 4
Hi from inside Wire module io.update_state 0
do something else
counter:   0
Hi from inside Wire module io.update_state 0
do something else
counter:   1
Hi from inside Wire module io.update_state 0
do something else
counter:   2
Hi from inside Wire module io.update_state 0
do something else
counter:   3

There are two def methods callable from when/.elsewhen clauses that update io.update_state value, but the wire stuck to the value in the latter def. If update wire directly from the when/.elsewhen clauses (the commented code in the clauses) the behavior will be correct:

./Test 4
Hi from inside Wire module io.update_state 1
do update state
counter:   0
Hi from inside Wire module io.update_state 0
do something else
counter:   1
Hi from inside Wire module io.update_state 1
do update state
counter:   2
Hi from inside Wire module io.update_state 1
do update state
counter:   3

Another issue - segfaults in commented now printf statements printf("test_touch... and printf("get_victim...

Thanks!

io's name gets overwritten when assigned to wire

ManglingOk produces the following Verilog code:

module ManglingOk(
input [7:0] io_input,
output[7:0] io_output
);
assign io_output = io_input;
endmodule

In contrast, ManglingBug produces

module ManglingBug(
input [7:0] input_,
output[7:0] io_output
);
assign io_output = input_;
endmodule

The only difference is that that ManglingBug reads io.input into a local
value before assigning it to io.output. I do not think that something
like that should change the external view of the module.

package example

import Chisel._
import Node._

class ManglingOk extends Module {
val io = new Bundle {
val input = Bits(INPUT, width = 8)
val output = Bits(OUTPUT, width = 8)
}
io.output := io.input
}

object ManglingOkMain {
def main(args: Array[String]): Unit = {
chiselMain(args, () => Module(new ManglingOk()))
}
}

class ManglingBug extends Module {
val io = new Bundle {
val input = Bits(INPUT, width = 8)
val output = Bits(OUTPUT, width = 8)
}
val input = io.input
io.output := input
}

object ManglingBugMain {
def main(args: Array[String]): Unit = {
chiselMain(args, () => Module(new ManglingBug()))
}
}

Chisel does not complain about forgetting INPUT/OUTPUT when defining fields in I/O bundle

I forgot to add INPUT/OUTPUT direction when defining fields in the I/O bundle. Chisel does not catch this, but it generates incorrect Verilog.

It would be nice if Chisel could catch this error before it gets to the Verilog compiler.

Error-[IND] Identifier not declared
/scratch/celio/boom/vlsi/build/generated-src/Top.v, 42091
  Identifier 'io_lsu_io_lsu_clr_bsy_rob_idx' has not been declared yet. If 
  this error is not expected, please check if you have set `default_nettype to
  none.

In lsu.scala:

val io = new Bundle {
    val lsu_clr_bsy_valid  = Bool() 
}

In Top.v:

   LoadStoreUnit lsu(.clk(clk), .reset(reset),
        .io_lsu_clr_bsy_rob_idx(  ),

Malformed Literals not caught by Chisel, cause error in C++ compilation.

Chisel will generate C++ code with constants like "0x-fL". That should actually be "-0xfL".

   val_t T16802__w0;
   { val_t __mask = -T16558__w0; 
        T16802__w0 = T16801__w0 ^ ((T16801__w0 ^ 0x-fL) & __mask); }

One way to fix this is to catch this cases and handle them in "Cpp.scala:wordMangle"

   var hex = x.asInstanceOf[Literal].value.toString(16)
   if (x.asInstanceOf[Literal].value < 0) println("OMG I found a negative value")
   if (hex.length > bpw/4*w) 
       "0x" +  hex.slice(hex.length-bpw/4*(w + 1), hex.length-bpw/4*w) + "L" 
   else "0L"

(Admittedly I've not tried to see what happens in the Verilog backend).

Of course, it is probably even better to catch these malformed literals before this step, since they are almost certainly invalid literal values.

In this particular example, my error was caused by using this literal in actual logic:

val OP_X = Bits("b????")

Obviously malformed. And a user error (it's suppose to be passed to a hand-rolled logic minimizer function, but I accidentally used it in a ListLookup table). This should get caught by the Chisel front-end and not the C++ backend.

negative wire widths in verilog

the following code gets through chisel and generates bad verilog

wire[-7:0] cs_3;
wire[-7:0] cs_2;
wire[-7:0] cs_1;
wire[-7:0] cs_0;

Wired declared over a negative range of indexes. Is this Verilog ok? This was generated from this statement, which breaks a 32-bit integer down into its component bytes:

val cs = Vec(Range(0, 4).map(i => io.in(i * 8, (i + 1) * 8 - 1)))

we should check this before generating verilog

DSL Extension to Verify Design Against Spec

Some sort of design verification extensions would be needed.

If the spec is not embedded in the design they can become inconsistent. So specification should be embeddable in the design code itself for automated verification.

Verilog generation of ROMs fails

The issue is with the clock domain, it fails on line 558 in Verilog.scala because clkDomains does not contain m.clock for the generated ROM.

548 def emitRegs(c: Module): StringBuilder = {
549 val res = new StringBuilder();
550 val clkDomains = new HashMap[Clock, StringBuilder]
551 for (clock <- c.clocks) {
552 val sb = new StringBuilder
553 sb.append(" always @(posedge " + emitRef(clock) + ") begin\n")
554 clkDomains += (clock -> sb)
555 }
556 for (m <- c.mods) {
557 if (m.clock != null){
558 clkDomains(m.clock).append(emitReg(m))
559 }
560 }

incorrect wiring leads to null pointer exception

the following code fails with null pointer exception. when gender of to/fromGrid is correctly reversed it works:

class FixHostSham extends Module {
val io = new Bundle {
val fromHost = Decoupled(UInt(width = 32)).flip
val toHost = Decoupled(UInt(width = 32))
val fromGrid = UInt(OUTPUT, 32)
val toGrid = UInt(INPUT, 32)
}

val fromHostQ = Module(new Queue(UInt(width = 32), 8))
val toHostQ = Module(new Queue(UInt(width = 32), 8))

fromHostQ.io.enq <> io.fromHost
toHostQ.io.deq <> io.toHost

fromHostQ.io.deq.ready := Bool(true)
io.toGrid := UInt(0)
when (fromHostQ.io.deq.valid) {
io.toGrid := fromHostQ.io.deq.bits
}
toHostQ.io.enq.bits := io.fromGrid
toHostQ.io.enq.valid := Bool(true)
}

C++ Emission Null Pointer Exception when creating SRAM-mappable Memory of a Bundle

See code in followup post for immediate example/test case. (It will fail during C++ emission.)

Attempting to instantiate a sequentially read memory of bundles cause an error when the graph is elaborated with the C++ backend. Some analysis of the stack trace indicates that the issue is likely related to the insertion of an LFSR to the response port (to simulate garbage when reading and writing to the same place).

This is not a highly critical issue since a workaround exists of only instantiating Mems of Bits and using getWidth/toBits/fromBits to convert from/to Bundle to/from Bits. However, this is clearly non-ideal (and the Null Pointer Exception dumped is rather user-unfriendly).

This has been a recurring issue across various Chisel versions and branches.
Edit: I had forgotten to mention. This bug does not seem to exist for the Verilog backend.

`build.sbt` file in README.md doesn't work

Running sbt run with the build script listed in README.md results in an error.

$ sbt run
[info] Set current project to default-11c8d0 (in build file:/home/bryan/src/chisel/)
[info] Updating {file:/home/bryan/src/chisel/}default-11c8d0...
[info] Resolving org.scala-lang#scala-library;2.10.2 ...
[info] Resolving edu.berkeley.cs#chisel_2.10.2;2.0.1 ...
[warn]  module not found: edu.berkeley.cs#chisel_2.10.2;2.0.1
[warn] ==== local: tried
[warn]   /home/bryan/.ivy2/local/edu.berkeley.cs/chisel_2.10.2/2.0.1/ivys/ivy.xml
[warn] ==== scct-github-repository: tried
[warn]   http://mtkopone.github.com/scct/maven-repo/edu/berkeley/cs/chisel_2.10.2/2.0.1/chisel_2.10.2-2.0.1.pom
[warn] ==== public: tried
[warn]   http://repo1.maven.org/maven2/edu/berkeley/cs/chisel_2.10.2/2.0.1/chisel_2.10.2-2.0.1.pom
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  ::          UNRESOLVED DEPENDENCIES         ::
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  :: edu.berkeley.cs#chisel_2.10.2;2.0.1: not found
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[error] {file:/home/bryan/src/chisel/}default-11c8d0/*:update: sbt.ResolveException: unresolved dependency: edu.berkeley.cs#chisel_2.10.2;2.0.1: not found
[error] Total time: 2 s, completed Sep 16, 2013 2:58:15 PM
$ cat build.sbt
scalaVersion := "2.10.2"

resolvers ++= Seq(
  "scct-github-repository" at "http://mtkopone.github.com/scct/maven-repo"
)

libraryDependencies += "edu.berkeley.cs" %% "chisel" % "2.0.1"

Chisel complains about "NO DEFAULT SPECIFIED" despite when/.otherwise being used

Chisel complains that a wire has no default specified, despite the fact that the wire has a value specified in both parts of a when/.otherwise statement.

Also... the "no default specified" error message is utterly useless... which wire is my design has no default specified?!


The Code:

val io = new Bundle                                                            
{                                                                                                      
    val imem = new MemPortIo(conf.xprlen).flip // instruction fetch             
    val dmem = new MemPortIo(conf.xprlen).flip // load/store                    
    val mem  = new MemPortIo(conf.xprlen)                                       
}                                                                              

when (req_fire_dmem)
{
   io.mem.req.valid     := io.dmem.req.valid
}  
.otherwise
{
   io.mem.req.valid     := io.imem.req.valid
}

The Error message:

Thread.java:1495: error: NO DEFAULT SPECIFIED FOR WIRE: OUTPUT(.) in class java.lang.Thread
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at BuildSettings$.runChisel(build.scala:40)
at BuildSettings$$anonfun$7$$anonfun$apply$1.apply(build.scala:46)
at BuildSettings$$anonfun$7$$anonfun$apply$1.apply(build.scala:46)
at sbt.Scoped$$anonfun$hf3$1.apply(Structure.scala:460)
at sbt.Scoped$$anonfun$hf3$1.apply(Structure.scala:460)
at scala.Function1$$anonfun$compose$1.apply(Function1.scala:41)
at sbt.Scoped$Reduced$$anonfun$combine$1$$anonfun$apply$9.apply(Structure.scala:271)
at sbt.Scoped$Reduced$$anonfun$combine$1$$anonfun$apply$9.apply(Structure.scala:271)
at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:40)
at sbt.std.Transform$$anon$5.work(System.scala:67)
Caused by: java.lang.IllegalStateException: CODE HAS 4 ERRORS/WARNINGS
at Chisel.ChiselError$.checkpoint(ChiselError.scala:119)
at Chisel.Backend.elaborate(Backend.scala:315)
at Chisel.CppBackend.elaborate(Cpp.scala:555)
at Chisel.chiselMain$.apply(hcl.scala:195)
at Chisel.chiselMain$.run(hcl.scala:170)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at BuildSettings$.runChisel(build.scala:40)
at BuildSettings$$anonfun$7$$anonfun$apply$1.apply(build.scala:46)
at BuildSettings$$anonfun$7$$anonfun$apply$1.apply(build.scala:46)
at sbt.Scoped$$anonfun$hf3$1.apply(Structure.scala:460)
at sbt.Scoped$$anonfun$hf3$1.apply(Structure.scala:460)
[error] {file:/scratch/celio/sodor/sbt/}rv32_3stage/*:elaborate: java.lang.reflect.InvocationTargetException

Width inference takes hours, needs to quickly detect and throw error on un-inferable code

I have accidentally written a piece of Chisel code that should error out, but doesn't. Instead, inference chugs happily along for hours before I get tired of waiting for it to loop through nodesList and quit out.

This is the offending code...

class SomethingIO extends Bundle
{
    val debug = new Bundle                                     
    {                                                               
       val entry = Vec.fill(num_entries) { new Bundle {   
          val valid = Bool()                                   
          val eflags = UInt() // THIS IS THE CULPRIT  
       }}                                                      
    }.asOutput                                                 
}

The problem is I didn't hook anything up to io.debug.entry(*).eflags, thus Chisel can't infer its width. Admittedly my bad... but I shouldn't be punished with a couple hour compile time.

In the backend, this code goes to Module.inferAll(), looping through every Node exhaustively. It will never hit "done" though, because this one node (io.debug.entry(*).eflags) will always be "width = -1", and no forward progress will ever be made to resolve it.

Is there a way to recognize a node of width -1 is unconnected, and should be removed from width inference? (or throw an error).

Also, "inferCount" looks like it intends to catch infinite loops in Node.infer(), but it is never incremented. However, it won't work correctly anyways to detect an un-inferable Node... it will just list out ALL nodes in a design, since Chisel appears to loop over ALL NODES even if just one node is still being "updated" (i.e., has width of -1).

Requests:

  • detect un-inferable nodes (width = -1 and has no inputs).
  • Throw error quickly so I can fix my bad Chisel code
  • Node.infer() -> if(inferCount > 1000000) is not adequate to detect un-inferable node. Must check for (res != width || res == -1) too. Unfortunately this is a fail slow catch (and relies on magic numbers).

P.S.
As a fun side thought, I think it's hilarious that the following compiles with no issues:

val io = new Bundle { val out = Bits(OUTPUT, width = 32) }
val counter = Reg(UInt())
counter := counter
io.out := counter

"counter" becomes a 1-wide register, but I have no idea why this code works or how 1-bit width was decided on.

log2Up(1) returns 1, instead of the correct answer of 0

For book-keeping sake, I'm adding this issue to the issue log.

Problem

There's a bug/hack in Log2Up() (and down) which returns the wrong answer (it returns 1 instead of 0).

Unfortunately, a lot of code uses Log2Up() to create address widths, as it hides away the possibility of having a 0-bit wire by returning Log2Up(1) = 1.

Example:

val addr = UInt(width=Log2Up(1))

This shows up even in the backend, for something like Mem(), for when num_entries == 1, and thus the address into the 1-entry memory is 1-bit (even though the address is irrelevant in such a case).

Proposed solution:

Add support to Chisel for 0-width wires. They are inherently literals, and should be constant-folded away and thus never touch the backend.

Some warts are how to deal with zero-bit registers, which should be removed from the design:

val r = Reg(init = UInt(0,0))
r := r + UInt(1,1)

Init needs to force the width of "r" if a width is specified. Currently this will become a 1-bit counter.

Verilog backend not work when wiring bundle from a class to another IO pin

I have a scala class ModInt that looks like:

class ModInt extends Bundle {
val dat = new BigUInt()
val mod = new BigUInt()

def +...

}

and BigUInt looks like:
class BigUInt() extends Bundle {
val data = UInt(INPUT, 256)
val oflo = Bool(INPUT)

def...
}

when I instantiate a ModInt object, myModInt, and then try to wire myModInt.dat.data to an IO pin of a chisel module:

val modularMultiply = Module(new modMultiply())
val myModInt = new ModInt
...
modularMultiply.io.operandA := myModInt.dat.data

the Verilog backend breaks (The C backend works perfectly fine), I get the following error:

// COMPILING class Work.pointAdder(2)
started inference
finished inference (11)
start width checking
finished width checking
started flattenning
finished flattening (630)
resolving nodes to the components
error java.lang.NullPointerException
java.lang.NullPointerException
at Chisel.Backend.collectNodesIntoComp(Backend.scala:311)
at Chisel.Backend.elaborate(Backend.scala:525)
at Chisel.VerilogBackend.elaborate(Verilog.scala:767)
at Chisel.chiselMain$.apply(hcl.scala:203)
at Work.Work$.main(work.scala:8)
at Work.Work.main(work.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)

printf doesn't work with chisel tester

currently printf doesn't work with chisel tester because chisel tester uses stdin/out. one possible solution is to have printf use stderr (or to have tester use sockets).

Discrepency in Verilog and Chisel Behavior for Shifts

A student just ran into the following bug.

val addr = Bits(INPUT, 6)
...
val tagArray = Reg(init=Bits(0, 64))
tagArray := tagArray | (UInt(1)<<io.addr)

In Chisel this performs the shift and tagArray is updated correctly. In Verilog UInt(1) is set to a width of 1 bit and so the shift doesn't do anything.

Give Better Error Message When Using Bundle Field that Is Not In View

Currently, if you attempt to use a bundle field that you have removed from the bundle's view, you receive the warning below:

// UNCONNECTED BITS(, OUTPUT(.Slice)) IN Slice

A better warning message that states what field and bundle cause this message would be great as this error message means nothing to me.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.