Skip to content

Commit

Permalink
Register in SV
Browse files Browse the repository at this point in the history
  • Loading branch information
schoeberl committed May 27, 2023
1 parent 9e11360 commit 9f9f992
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 3 deletions.
22 changes: 22 additions & 0 deletions chisel-book.tex
Original file line number Diff line number Diff line change
Expand Up @@ -6915,13 +6915,35 @@ \section{Code Examples}
\longlist{code/sv_ch_adder.txt}{A simple module in Chisel.}{lst:sv:ch:adder}
Components are organized as modules in SV.
Listing~\ref{lst:sv:adder} shows a SV module with two 8-bit inputs and one 8-bit
output. The main body of the module uses the SV construct \code{always\_comb}
to declare that this code block describes combinational logic.
Listing~\ref{lst:sv:ch:adder} shows the some component in Chisel.
For such a simple component the difference between SV and Chisel is minimal.
\longlist{code/sv_register.txt}{A register with reset and enable in SystemVerilog.}{lst:sv:register}
Listing~\ref{lst:sv:register} shows a module that contains the definition of a
register (\code{reg\_data}) with a synchronous reset and an enable input in SystemVerilog.
The SV \code{reg} keywords declares a variable. This does not necessarily mean
that the variable represents a register. It can also represent combinational logic,
when used in an \code{always\_comb} block.
The \code{always \@} statement with a clock implies that the code within that block
represents a register. Registers are defined implicitly by a code pattern in Verilog
and VHDL. Whereas, in Chisel the registers are defined explicitly.
The \code{assign} statement is a concurrent statement that continuously
assigns the value of the register to the output port \code{out}.
\longlist{code/sv_ch_register.txt}{A register with reset and enable in Chisel.}{lst:sv:ch:register}
Listing~\ref{lst:sv:ch:register} show the register with reset and enable in Chisel, using
the three-parameter version of \code{RegEnable}.
\todo{use logic in the parameters and explain that this is the new way in SV.}
\section{External Modules and Integration of Legacy Code}
Expand Down
65 changes: 63 additions & 2 deletions src/main/scala/verilog/basic.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,67 @@ class AdderTop extends Module {
io.s := ch.io.sum
}

object Adder extends App {
println(getVerilogString(new AdderTop()))
class Register extends BlackBox with HasBlackBoxInline {
val io = IO(new Bundle() {
val clk = Input(Clock())
val reset, enable = Input(UInt(1.W))
val data = Input(UInt(8.W))
val out = Output(UInt(8.W))
})

setInline("Register.sv",
"""
//- start sv_register
module Register(
input wire clk,
input wire reset,
input wire enable,
input wire [7:0] data,
output wire [7:0] out
);
reg [7:0] reg_data;
always @(posedge clk) begin
if (reset)
reg_data <= 0;
else if (enable)
reg_data <= data;
end
assign out = reg_data;
endmodule
//- end
""")}

//- start sv_ch_register
class ChiselRegister extends Module {
val io = IO(new Bundle{
val enable = Input(Bool())
val data = Input(UInt(8.W))
val out = Output(UInt(8.W))
})

io.out := RegEnable(io.data, 0.U(8.W), io.enable)
}
//- end

class RegisterTop extends Module {
val io = IO(new Bundle() {
val in = Input(UInt(8.W))
val out = Output(UInt(8.W))
val out2 = Output(UInt(8.W))
val en = Input(UInt(1.W))
})

val m = Module(new Register)
m.io.clk := clock
m.io.reset := reset
m.io.enable := io.en
m.io.data := io.in
io.out := m.io.out
val cm = Module(new ChiselRegister)
cm.io.enable := io.en
cm.io.data := io.in
io.out2 := cm.io.out
}
27 changes: 26 additions & 1 deletion src/test/scala/verilog/BasicTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import org.scalatest.flatspec.AnyFlatSpec

class BasicTest extends AnyFlatSpec with ChiselScalatestTester {
"Adder" should "pass" in {
test(new AdderTop()).withAnnotations(Seq(VerilatorBackendAnnotation)) { dut =>
test(new AdderTop()).withAnnotations(Seq(VerilatorBackendAnnotation)) { dut =>
dut.io.a.poke(1.U)
dut.io.b.poke(3.U)
dut.clock.step()
Expand All @@ -17,4 +17,29 @@ class BasicTest extends AnyFlatSpec with ChiselScalatestTester {
dut.io.s.expect(4.U)
}
}

"Register" should "pass" in {
test(new RegisterTop()).withAnnotations(Seq(VerilatorBackendAnnotation)) { dut =>
dut.io.en.poke(1.U)
dut.io.in.poke(1.U)
dut.io.out.expect(0.U)
dut.io.out2.expect(0.U)
dut.clock.step()
dut.io.out.expect(1.U)
dut.io.out2.expect(1.U)
dut.io.in.poke(123.U)
dut.io.out.expect(1.U)
dut.io.out2.expect(1.U)
dut.clock.step()
dut.io.out.expect(123.U)
dut.io.out2.expect(123.U)
dut.io.in.poke(45.U)
dut.io.en.poke(0.U)
dut.io.out.expect(123.U)
dut.io.out2.expect(123.U)
dut.clock.step()
dut.io.out.expect(123.U)
dut.io.out2.expect(123.U)
}
}
}

0 comments on commit 9f9f992

Please sign in to comment.