forsyde / forsyde-deep

Other
1 stars 2 forks source link

take in FSVec #40

Closed fuzhouxiang closed 6 months ago

fuzhouxiang commented 1 year ago

Hi, I found that the generated VHDL code for 'take' function in Data.Param.FSVec cannot be simulated by writeAndModelsimVHDL. Here is a small example.

{-# LANGUAGE TemplateHaskell #-}
module Take where
import ForSyDe.Deep
import Data.Int
import Data.TypeLevel
import Data.Param.FSVec

takeProcFun :: ProcFun(FSVec D3 Int32 -> FSVec D1 Int32)
takeProcFun = $(newProcFun
    [d| takeProcFun :: FSVec D3 Int32 -> FSVec D1 Int32
        takeProcFun x = Data.Param.FSVec.take d1 x
    |])

takeProc :: Signal (FSVec D3 Int32) -> Signal (FSVec D1 Int32)
takeProc = mapSY "proc1" takeProcFun

takeSysDef :: SysDef(Signal (FSVec D3 Int32) -> Signal (FSVec D1 Int32))
takeSysDef = newSysDef takeProc "mingzi" ["in"] ["out"]

x1 = (1 :: Int32) +> (2 :: Int32) +> (3 :: Int32) +> empty
x2 = (4 :: Int32) +> (5 :: Int32) +> (6 :: Int32) +> empty

The simulation in ForSyDe.Deep is fine.

simulate takeSysDef [x1, x2]
[<1>,<4>]

But the simulation in Modelsim failed.

writeAndModelsimVHDL Nothing takeSysDef [x1, x2]
Running: vmap forsyde /home/embedded/Downloads/deep/.stack-work/install/x86_64-linux-tinfo6/41f3446f00eaf30900387f62586718ab816bbd89d646a1e0d09fd9d4762383ee/8.0.2/share/x86_64-linux-ghc-8.0.2/forsyde-deep-0.2.0/lib/modelsim
Model Technology ModelSim - Intel FPGA Edition vmap 2020.1 Lib Mapping Utility 2020.02 Feb 28 2020
vmap forsyde /home/embedded/Downloads/deep/.stack-work/install/x86_64-linux-tinfo6/41f3446f00eaf30900387f62586718ab816bbd89d646a1e0d09fd9d4762383ee/8.0.2/share/x86_64-linux-ghc-8.0.2/forsyde-deep-0.2.0/lib/modelsim 
Modifying modelsim.ini
Running: vlib mingzi_lib/modelsim
** Warning: (vlib-34) Library already exists at "mingzi_lib/modelsim".
Running: vcom -93 -quiet -nologo -work mingzi_lib/modelsim mingzi_lib/mingzi_lib.vhd
** Warning: mingzi_lib/mingzi_lib.vhd(127): (vcom-1246) Range 0 to -1 is null.
Running: vmap mingzi_lib mingzi_lib/modelsim
Model Technology ModelSim - Intel FPGA Edition vmap 2020.1 Lib Mapping Utility 2020.02 Feb 28 2020
vmap mingzi_lib mingzi_lib/modelsim 
Modifying modelsim.ini
Running: vlib work/modelsim
** Warning: (vlib-34) Library already exists at "work/modelsim".
Running: vcom -93 -quiet -nologo -work work/modelsim -just e work/mingzi.vhd
Running: vcom -93 -quiet -nologo -work work/modelsim -just a work/mingzi.vhd
Running: vmap work work/modelsim
Model Technology ModelSim - Intel FPGA Edition vmap 2020.1 Lib Mapping Utility 2020.02 Feb 28 2020
vmap work work/modelsim 
Modifying modelsim.ini
Running: vcom -93 -quiet -nologo -work work test/mingzi_tb.vhd
Running: vsim -c -std_output /tmp/tb_out7198853861649760492.txt -quiet -do run 20 ns; exit work.mingzi_tb
Reading pref.tcl

# 2020.1

# vsim -c -std_output /tmp/tb_out7198853861649760492.txt -quiet -do "run 20 ns; exit" work.mingzi_tb 
# Start time: 00:51:37 on Oct 23,2022
# run 20 ns
# ** Fatal: (vsim-3420) Array lengths do not match. Left is 1 (0 to 0). Right is 0 (1 to 0 (null array)).
#    Time: 0 ps  Iteration: 0  Process: /mingzi_tb/totest/\proc1\/line__31 File: mingzi_lib/mingzi_lib.vhd
# Fatal error in Subprogram take at mingzi_lib/mingzi_lib.vhd line 187
# 
# HDL call sequence:
# Stopped at mingzi_lib/mingzi_lib.vhd 187 Subprogram take
# called from  work/mingzi.vhd 28 Subprogram \takeProcFun_0\
# called from  work/mingzi.vhd 31 Block \proc1\
# 
#  exit
# End time: 00:51:37 on Oct 23,2022, Elapsed time: 0:00:00
# Errors: 1, Warnings: 0
[]

For the simulation in Quartus, I am still struggling.

ingo-sander commented 1 year ago

Analysis of bug report

forsyde-deep produces the wrong code for the function take in mingzi_lib/mingzi_lib.vhd.

The following code is produced in line 182-189:

     function take (n : natural;
                    vec : fsvec_int32)
                   return fsvec_int32 is
          variable res : fsvec_int32 (0 to n - 1);
     begin
          res := vec(1 to n - 1);
          return res;
     end;

The following code should be produced:

     function take (n : natural;
                    vec : fsvec_int32)
                   return fsvec_int32 is
          variable res : fsvec_int32 (0 to n - 1);
     begin
          res := vec(0 to n - 1);
          return res;
     end;

So, for the lower index in line 187 in the function take

          res := vec(1 to n - 1); -- wrong code

a 0 needs to be generated instead of a 1.

          res := vec(1 to n - 1); -- correct code
ingo-sander commented 1 year ago

Error Fix A solution to fix this error has been included in the development branch.

fuzhouxiang commented 1 year ago

The forsyde-deep in the development branch works well for writeandmodelsimvhdl.

ingo-sander commented 6 months ago

It has now been integrated into the main branch.