log-D202409003
Opened this issue · 15 comments
1.6.004 视频L01-L12,基本上是一些基础知识
2.6.175 lab1-2,网站挂了,做的2016年的,备份的2017的跟仓库里同步的代码有点出入,由于不着急,再等等吧
1.仔细看了看lab3,FFT的一些写法,尤其是最后的蝶形单元和Stage都折叠的写法,有点绕,主要是各种数据类型各种位宽很难搞。
2.lab3里面的很多rule都有不同的写法,有些很写法就不能奏效,例如
rule doFft;
//TODO: Implement the rest of this module
let n = fromInteger(valueOf(NumStages));
//BUG: Why is it wrong? -> Some conflict? Maybe the function stage_f's input is not the same at different if-else cases, so it consider a multi-driven?
//Solve: 1. If replace stage_f(k, inFifo.first/sReg) as stage_f(k, sxIn) and write let sxIn = k == 0 ? inFifo.first : sReg;, this will work..., wierd!
//Solve: 2. Add (* split *) to the if-else
// (* split *)
let sxIn = k == 0 ? inFifo.first : sReg;
if(k == 0) begin
inFifo.deq;
sReg <= stage_f(k, sxIn);
end else if(k == n - 1) begin
outFifo.enq(stage_f(k, sxIn));
end else begin
sReg <= stage_f(k, sxIn);
end
// This works, shown in the lecture
// let sxIn = ?;
// if (k == 0) begin
// inFifo.deq;
// sxIn = inFifo.first;
// end else begin
// sxIn = sReg;
// end
// let sxOut = stage_f(k, sxIn);
// if(k == n - 1) begin
// outFifo.enq(sxOut);
// end else begin
// sReg <= sxOut;
// end
k <= (k == n - 1) ? 0 : k + 1;
endrule
这里面注释说明了情况,为什么在if-else里写stage_f这个函数,如果传参不一样就会报错?想这个耽误了一些时间。
具体的,比如在k==0,有sReg <= stage_f(k, inFifo.first),在k==n-1时有 outFifo.enq(stage_f(k, sReg));,会报错。
补充一下lab3里面inelastic的pipeline的写法,这里用寄存器和valid位来做中间buffer,参考的写法(lecture里面有提到):
if(outFifo.notFull || sReg1v == Invalid) begin
if(inFifo.notEmpty) begin
inFifo.deq;
sReg0 <= stage_f(0, inFifo.first);
sReg0v <= Valid;
end else begin
sReg0v <= Invalid;
end
sReg1 <= stage_f(1, sReg0);
sReg1v <= sReg0v;
if(sReg1v == Valid) outFifo.enq(stage_f(2, sReg1));
end
这样就是在outFifo满和第二个寄存器valid时,不能写入第一个寄存器,算是跨级反压?这样第一个寄存器stall,虽然可能他是invalid能接受一个inFifo的数据,改成这样是不是更合理一些?
// Add sReg0v == Invalid to avoid above issue
let sReg1Rdy = outFifo.notFull || sReg1v == Invalid;
let sReg0Rdy = sReg1Rdy || sReg0v == Invalid;
if(sReg0Rdy) begin
if(inFifo.notEmpty) begin
inFifo.deq;
sReg0 <= stage_f(0, inFifo.first);
sReg0v <= Valid;
end else begin
sReg0v <= Invalid;
end
end
if(sReg1Rdy) begin
sReg1 <= stage_f(1, sReg0);
sReg1v <= sReg0v;
if(sReg1v == Valid) outFifo.enq(stage_f(2, sReg1));
end
这样类似pipeline的逐级反压,不知道会不会更准确一些,也或许课程的inelastic方法就是要实现类似的跨级反压?
I think your design is better ! 👍
@myrfy001 Can you help me figure out why the code in the module mkFftFolded in my repo
(Please copy and paste the link but not just click it)
https://github.com/xiaoan109/MIT-course-training/blob/main/6.175-lab3/Fft.bsv (line 64)does not work?
Specifically,code like this
if(k == 0) begin
inFifo.deq;
sReg <= stage_f(k, inFifo.first);
end else if(k == n - 1) begin
outFifo.enq(stage_f(k, sReg));
end else begin
sReg <= stage_f(k, sReg);
end
gives an Error, but code like this
let sxIn = k == 0 ? inFifo.first : sReg;
if(k == 0) begin
inFifo.deq;
sReg <= stage_f(k, sxIn);
end else if(k == n - 1) begin
outFifo.enq(stage_f(k, sxIn));
end else begin
sReg <= stage_f(k, sxIn);
end
works fine ?
6.175-lab4 finished.
(Please copy and paste the link but not just click it)
Question:In https://github.com/xiaoan109/MIT-course-training/blob/main/6.175-lab4/discussion.txt,the second one.
In the conflict matrix, first CF enq or first < enq ?
My answer: I think read from data[deqP] and write into data[enqP] while deqP == enqP can not happen at the same cycle.
Because when the two ptr are the same, the CFIFO is either full or empty, so enq and first would not execute concurrently.
But I do not know whether writing to a Vector of Registers is considered as a conflict.
you can (and should) design some simple testcase and find the answer of the questions that bother you by yourself.
@myrfy001 Can you help me figure out why the code in the module mkFftFolded in my repo (Please copy and paste the link but not just click it) https://github.com/xiaoan109/MIT-course-training/blob/main/6.175-lab3/Fft.bsv (line 64)does not work? Specifically,code like this
if(k == 0) begin inFifo.deq; sReg <= stage_f(k, inFifo.first); end else if(k == n - 1) begin outFifo.enq(stage_f(k, sReg)); end else begin sReg <= stage_f(k, sReg); end
gives an Error, but code like this
let sxIn = k == 0 ? inFifo.first : sReg; if(k == 0) begin inFifo.deq; sReg <= stage_f(k, sxIn); end else if(k == n - 1) begin outFifo.enq(stage_f(k, sxIn)); end else begin sReg <= stage_f(k, sxIn); end
works fine ?
I don't have time to clone and run your code. When ask questions about some compiler or simulation runtime error, you need to paste the error message.
- #55 (comment) #55 (comment)
OK. Find time to get the truth of the confused things. - 6.735 lab1 finished. Using yosys-sta repo instead of the origin Makefile because the latter one may depens on the MIT lab machine which is not suitable for us.
6.175-lab4 finished. (Please copy and paste the link but not just click it) Question:In https://github.com/xiaoan109/MIT-course-training/blob/main/6.175-lab4/discussion.txt,the second one. In the conflict matrix, first CF enq or first < enq ? My answer: I think read from data[deqP] and write into data[enqP] while deqP == enqP can not happen at the same cycle. Because when the two ptr are the same, the CFIFO is either full or empty, so enq and first would not execute concurrently. But I do not know whether writing to a Vector of Registers is considered as a conflict.
I got to know that the method first shouble be < method enq rather than CF.
The reason is that when the method first want to read the data Register Vectors,it dose not only read the certain one with index == deqP, but read all the data Regs and muxes the needed one. So it should be the same as the CM in a Reg _write and _read, all the data Regs will be read before write, so the method first < method enq.
(We should consider the whole things in a hardware view!)
@myrfy001 Can you help me figure out why the code in the module mkFftFolded in my repo (Please copy and paste the link but not just click it) https://github.com/xiaoan109/MIT-course-training/blob/main/6.175-lab3/Fft.bsv (line 64)does not work? Specifically,code like this
if(k == 0) begin inFifo.deq; sReg <= stage_f(k, inFifo.first); end else if(k == n - 1) begin outFifo.enq(stage_f(k, sReg)); end else begin sReg <= stage_f(k, sReg); end
gives an Error, but code like this
let sxIn = k == 0 ? inFifo.first : sReg; if(k == 0) begin inFifo.deq; sReg <= stage_f(k, sxIn); end else if(k == n - 1) begin outFifo.enq(stage_f(k, sxIn)); end else begin sReg <= stage_f(k, sxIn); end
works fine ?
if(k == 0) begin
inFifo.deq;
sReg <= stage_f(k, inFifo.first);
end else if(k == n - 1) begin
outFifo.enq(stage_f(k, sReg));
end else begin
sReg <= stage_f(k, sReg);
end
❌generates an Error
Error: "Fft.bsv", line 67, column 24: (G0002)
`bfly_0.bfly4' needs more than 1 ports for the following uses:
`bfly_0.bfly4 _3_QUOT_2_PLUS_0_CONCAT_k_9_4_SRL_6_5_6_56_CONC_ETC___d366
IF_inFifo_da_virtual_reg_1_read__09_OR_inFifo__ETC___d368' at "Fft.bsv",
line 67, column 24
`bfly_0.bfly4 _3_QUOT_2_PLUS_0_CONCAT_k_9_4_SRL_6_5_6_56_CONC_ETC___d366
sReg_21_BITS_63_TO_0___d497' at "Fft.bsv", line 67, column 24
✔Finally, I figured out that the different if-else statements call the same function stage_f, and the stage_f put the input to the MODULE mkBfly4(its interface Bfly4, in detail), so it just like the multi-driver in Verilog (if we do not use some complie flags)!
The solutions which are mentioned above are:
1.Use a internal variable to choose the function input,it works like a mux before a module.
2.Add the (* split *) attribute.
3.Split the three if-else into three indepent rules.(like 2)
4.Add compile flags -split-if(like 2), which is recommended in bsc-user-guide when the -aggressive-conditions flag used.
Good work!
6.375 lab2 finished. Some issues revealed in discussion.txt.
Recently I am participating a FPGA competition.
6.375 lab3 finished.
I found that we can use the synth tool in this repo https://github.com/minispec-hdl/minispec to synthesize circuits instead of yosys-sta. A little bit modification is needed which is shown in this issue https://github.com/minispec-hdl/minispec/issues/3.
6.375 lab4 finished.
HW-SW co-simulation is a good idea. But now I haven't learn the details in connectal_test.cpp.