Assign vec to UInt ports - scala

if I have a io port which is io.myoutput = UInt(width = 840)
Then I have a val a = vec.fill(140){UInt(width = 6)}
How do i assign the entire a vec into the output port? I tried for loop with
for (i = 0 until 140){
io.myoutput(i*6+5,i*6) := a(i)}
But it gives me
finished inference (1)
start width checking
finished width checking
started flattenning
finished flattening (2)
Lbi.scala:37: error: reassignment to Node in class TutorialExamples.Lbi
Lbi.scala:37: error: reassignment to Node in class TutorialExamples.Lbi
Lbi.scala:37: error: reassignment to Node in class TutorialExamples.Lbi
Thanks

val x = Vec.fill(140){UInt(1, width=6)}
io.myoutput := x.toBits
The "toBits" method is what you want. It flattens a Vec into its raw bits.
I'm not sure exactly what is causing the error message, but in general, you can't really reassign to specific bits in a wire in Chisel.
val y = Bits(0,width=32)
y(1) := UInt(0)
y(3) := UInt(3)
etc.
That will throw an error.

Related

RegInit initializes value only on reset

I am implementing a pulse width modulation module to learn chisel3.
The module code is:
import chisel3._
import chisel3.util._
import chisel3.tester._
class Pwm(bitWidth: Int) extends Module {
val io = IO(new Bundle {
val duty = Input(UInt(bitWidth.W))
val period = Input(UInt(bitWidth.W))
val output = Output(Bool())
})
val context = RegInit(0.U(bitWidth.W))
val output = RegInit(false.B)
val sum = Wire(UInt(bitWidth.W + 1))
sum := context +& io.duty
when (sum >= io.period) {
context := sum - io.period
output := true.B
} otherwise {
context := sum
output := false.B
}
io.output := output
}
I was expecting the registers to be initialized to their RegInit values when I emit verilog with:
val emit_args = Array("--emission-options=disableMemRandomization,disableRegisterRandomization");
chisel3.emitVerilog(new Pwm(8), emit_args)
But I get the following verilog code:
module Pwm(
input clock,
input reset,
input [7:0] io_duty,
input [7:0] io_period,
output io_output
);
reg [7:0] context_; // #[Pwm.scala 12:26]
reg output_; // #[Pwm.scala 13:25]
wire [8:0] sum = context_ + io_duty; // #[Pwm.scala 15:20]
wire [8:0] _GEN_2 = {{1'd0}, io_period}; // #[Pwm.scala 17:15]
wire _T = sum >= _GEN_2; // #[Pwm.scala 17:15]
wire [8:0] _context_T_1 = sum - _GEN_2; // #[Pwm.scala 18:24]
wire [8:0] _GEN_0 = sum >= _GEN_2 ? _context_T_1 : sum; // #[Pwm.scala 17:29 18:17 21:17]
wire [8:0] _GEN_4 = reset ? 9'h0 : _GEN_0; // #[Pwm.scala 12:{26,26}]
assign io_output = output_; // #[Pwm.scala 25:15]
always #(posedge clock) begin
context_ <= _GEN_4[7:0]; // #[Pwm.scala 12:{26,26}]
if (reset) begin // #[Pwm.scala 13:25]
output_ <= 1'h0; // #[Pwm.scala 13:25]
end else begin
output_ <= _T;
end
end
endmodule
Note that in the code context_ is set to 0 when reset is high but it is not initialized that way.
Is there an emission argument that allows registers to be initialized with the RegInit value?
In Chisel 3, RegInit is referring to a register with reset. There is experimental support for treating an asynchronous reset line as an "initial" line instead, but I want to caution that it's not something I would recommend using in typical digital design.
As you are probably aware, initial values are not universally supported in actual hardware. They are supported by some (but not all) FPGAs, and are not supported at all in ASICs. Thus writing code that relies on initial values is inherently unportable which runs counter to the ethos of Chisel for constructing resuable hardware generators.
That being said, they can make certain designs use resources on certain FPGAs much more efficiently, so we do have a way to do this:
// RequireAsyncReset makes the implicit reset Async because the default is Sync (only for top-level module)
// Only AsyncReset can be emitted as an initial value
class Pwm(bitWidth: Int) extends Module with RequireAsyncReset {
val io = IO(new Bundle {
val duty = Input(UInt(bitWidth.W))
val period = Input(UInt(bitWidth.W))
val output = Output(Bool())
})
val context = RegInit(0.U(bitWidth.W))
val output = RegInit(false.B)
val sum = Wire(UInt(bitWidth.W + 1))
sum := context +& io.duty
when (sum >= io.period) {
context := sum - io.period
output := true.B
} otherwise {
context := sum
output := false.B
}
io.output := output
// Experimental API
annotate(new ChiselAnnotation {
def toFirrtl = firrtl.annotations.PresetAnnotation(reset.toTarget)
})
}
I've tweaked your design to use async reset and used the experimental support for emitting initial values. (Scastie: https://scastie.scala-lang.org/rQtHVUCZROul4i1uEjClPw)
This is using Chisel v3.5.0. There is an important bug that was recently fixed (fix to be released in v3.5.1), and there is active discussion on how to expose this experimental API directly in Chisel without having to use FIRRTL annotations: https://github.com/chipsalliance/chisel3/pull/2330.

Callback in Bender's decomposition

I am learning Bender's decomposition method and I want to use that in a small instance. I started from "bendersatsp.py" example in CPLEX. When I run this example with my problem, I got the following error. Could you please let me know what the problem is and how I can fix it? In the following you can see the modifications in lazy constraints function. I have two decision variables in master problem "z_{ik}" and "u_{k}" that would incorporate as constant in the workerLp.
class BendersLazyConsCallback(LazyConstraintCallback):
def __call__(self):
print("shoma")
v = self.v
u = self.u
z = self.z
print ("u:", u)
print ("z:", z)
workerLP = self.workerLP
boxty = len(u)
#scenarios=self.scenarios2
ite=len(z)
print ("ite:", ite)
print ("boxty:", boxty)
# Get the current x solution
sol1 = []
sol2 = []
sol3 = []
print("okkkk")
for k in range(1, boxty+1):
sol1.append([])
sol1[k-1]= [self.get_values(u[k-1])];
print ("sol1:", sol1[k-1])
for i in range(1, ite+1):
sol2.append([])
sol2[i-1]= self.get_values(z[i-1]);
print ("sol2:", sol2[i-1])
for i in range(1, ite+1):
sol3.append([])
sol3[i-1]= self.get_values(v[i-1]);
#print ("sol3:", sol3[i-1])
# Benders' cut separation
if workerLP.separate(sol3,sol1,sol2,v,u,z):
self.add(cut = workerLP.cutLhs, sense = "G", rhs = workerLP.cutRhs)
CPLEX Error 1006: Error during callback.
benders(sys.argv[1][0], datafile)
cpx.solve()
_proc.mipopt(self._env._e, self._lp)
check_status(env, status)
raise callback_exception
TypeError: unsupported operand type(s) for +: 'int' and 'list'

Julia: Inexact error when trying to get the integer part of a BigFloat

I am interested in getting the digits of a BigFloat in the form of bytes. I get a very strange error that I cannot debug. I provide a minimal example where the error appears.
function floatToBytes(x::BigFloat)
ret = zeros(UInt8, 4)
xs = significand(x)/2
b = UInt8(0)
for i = 1:4
xs *= 256
b = trunc(UInt8, xs)
ret[i] = b
xs -= b
end
return ret
end
println( floatToBytes(BigFloat(0.9921875001164153)) )
println( floatToBytes(BigFloat(0.9960937501164153)) )
What I get when running this is
UInt8[0xfe, 0x00, 0x00, 0x00]
ERROR: LoadError: InexactError()
Stacktrace:
[1] trunc(::Type{UInt8}, ::BigFloat) at ./mpfr.jl:201
etc.
It seems that it doesn't want to turn 255 into a UInt8. I can circumvent the problem by defining the function as
function floatToBytes(x::BigFloat)
ret = zeros(UInt8, 4)
xs = significand(x)/2
b = UInt8(0)
for i = 1:4
xs *= 256
try
b = trunc(UInt8, xs)
catch
b = trunc(UInt8, xs-1)+UInt8(1)
end
ret[i] = b
xs -= b
end
return ret
end
But this is highly unsatisfactory. What is going on here?
The problem looks like a bug in trunc for BigFloat. The problem is the current code does (typemin(T) <= x <= typemax(T)) || throw(InexactError(:trunc, T, x)) which throws an error because x is larger than 255 which is the typemax.
It actually needs to do the trunc in BigFloat domain and then cast to T (and have the cast check for typemax).
I've opened an issue regarding this at: https://github.com/JuliaLang/julia/issues/24041
In the meantime, a solution could be to do:
UInt8(trunc(xs))
i.e. trunc first and cast later. For example:
julia> UInt8(trunc(BigFloat(0.9960937501164153)*256))
0xff

Imprecise Assigned value

In a simple program I want to build a matrix by defining a function. The problem is that a variable declared and initialized in the program has the exact assinged value of zero (zero_test)and some components of the matrix(D(4,1), D(1,4) etc.) which are assigned to 0., are not exactly zero. The latter have a value of order E-308 or E-291etc. I wonder why is there a difference.
Due to some articles I read, like this, the other components(D(1,1), D(1,2) etc.) are imprecise because of the transformation to the binary format.
System info: IA-32, Intel Visual Fortran 11.1.048 integrated with Microsoft Visual Studio 2008
The code:
program test
implicit none
real(8),parameter :: LAMBDA=75.e9,MU=50.e9
integer,parameter :: ndi=3,ntens=4
real(8) :: D(ntens,ntens),zero_test=0.
D = clcElasticStiffnessMatrix(LAMBDA,MU,ndi,ntens)
contains
function clcElasticStiffnessMatrix(LAMBDA,MU,ndi,ntens)
implicit none
integer :: ndi,ntens,i,j
real(8) :: clcElasticStiffnessMatrix(ntens,ntens),LAMBDA,MU
do i=1,ndi
do j=i,ndi
if(i .eq. j) then
clcElasticStiffnessMatrix(i,j) = 2.*MU + LAMBDA
else
clcElasticStiffnessMatrix(i,j) = LAMBDA
clcElasticStiffnessMatrix(j,i) = clcElasticStiffnessMatrix(i,j)
end if
end do
end do
do i=ndi+1,ntens
do j=i,ntens
if(i .eq. j) then
clcElasticStiffnessMatrix(i,j) = MU
else
clcElasticStiffnessMatrix(i,j) = 0.
clcElasticStiffnessMatrix(j,i) = clcElasticStiffnessMatrix(i,j)
end if
end do
end do
end function
end program
Matrix D in break mode:
D:
174999994368.000 74999996416.0000 74999996416.0000 2.641443384627243E-308
74999996416.0000 174999994368.000 74999996416.0000 2.640433316727162E-308
74999996416.0000 74999996416.0000 174999994368.000 -1.051992669438322E-291
2.640110775815455E-308 0.000000000000000E+000 6.151018477594351E-318 49999998976.0000
The problem is that you are assigning real(4) values to real(8) variables when you write
LAMBDA=75.e9,MU=50.e9
or
clcElasticStiffnessMatrix(i,j) = 0.
Try with d instead e and specify always:
LAMBDA=75.d9,MU=50.d9
clcElasticStiffnessMatrix(i,j) = 0.d0

Matlab function calling basic

I'm new to Matlab and now learning the basic grammar.
I've written the file GetBin.m:
function res = GetBin(num_bin, bin, val)
if val >= bin(num_bin - 1)
res = num_bin;
else
for i = (num_bin - 1) : 1
if val < bin(i)
res = i;
end
end
end
and I call it with:
num_bin = 5;
bin = [48.4,96.8,145.2,193.6]; % bin stands for the intermediate borders, so there are 5 bins
fea_val = GetBin(num_bin,bin,fea(1,1)) % fea is a pre-defined 280x4096 matrix
It returns error:
Error in GetBin (line 2)
if val >= bin(num_bin - 1)
Output argument "res" (and maybe others) not assigned during call to
"/Users/mac/Documents/MATLAB/GetBin.m>GetBin".
Could anybody tell me what's wrong here? Thanks.
You need to ensure that every possible path through your code assigns a value to res.
In your case, it looks like that's not the case, because you have a loop:
for i = (num_bins-1) : 1
...
end
That loop will never iterate (so it will never assign a value to res). You need to explicitly specify that it's a decrementing loop:
for i = (num_bins-1) : -1 : 1
...
end
For more info, see the documentation on the colon operator.
for i = (num_bin - 1) : -1 : 1