【数集项目之 MCDF】(二) 从输入端 slave_FIFO

news2024/11/17 1:49:18

  由于slave_FIFO调用了子模块同步FIFO SCFIFO.v,因此首先简单介绍同步FIFO的设计。

第一节 同步FIFOSCFIFO设计

  同步FIFO实体是一组存储单元,因此需要先用数组方式来实现

reg [DATA_WIDTH - 1 : 0]			fifo_buffer[DATA_DEPTH - 1 : 0];	

  其中在参数中进行如下定义,以满足本题的64深度32宽度FIFO

	parameter   DATA_WIDTH = 'd32  ,							//FIFO位宽
    parameter   DATA_DEPTH = 'd64 	

  同步FIFO有计数器实现读写地址实现这两种实现方式,这里采用的是读写地址实现。

reg [$clog2(DATA_DEPTH) : 0]		wr_ptr;						//写地址指针,位宽多一位	
reg [$clog2(DATA_DEPTH) : 0]		rd_ptr;						//读地址指针,位宽多一位	
																//wire define
wire [$clog2(DATA_DEPTH) - 1 : 0]	wr_ptr_true;				//真实写地址指针
wire [$clog2(DATA_DEPTH) - 1 : 0]	rd_ptr_true;				//真实读地址指针
wire								wr_ptr_msb;					//写地址指针地址最高位
wire								rd_ptr_msb;	
assign {wr_ptr_msb,wr_ptr_true} = wr_ptr;						//将最高位与其他位拼接
assign {rd_ptr_msb,rd_ptr_true} = rd_ptr;

  总共64个存储32位单元,为其编码0-63,因此需要6为地址线。而这里读写地址指针wr_ptr,rd_ptr都是[6:0]的7位,这是因为最高位是用来判断读空和写满的。低6位才是真实地址。因此我们通过assign把7位读写地址拆分成高1位和低6位
  代码主体通过两个always实现,分别是读always和写always,不同于控制寄存器,FIFO是可以同时读写的。首先是读always

//读操作,更新读地址
always @ (posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0)begin
		rd_ptr <= 'd0;//读地址清零
		fifo_buffer[0]<=0;//清空首地址数据
		data_out<=0;
	end
	else if (rd_en && !empty)begin								//读使能有效且非空
		data_out <= fifo_buffer[rd_ptr_true];
		rd_ptr <= rd_ptr + 1'd1;
	end
end

  当清零信号到来时,读地址归零,并且清空首地址数据。同时让输出也归零。
  正常工作时,根据时钟上升沿锁存的读真实地址rd_ptr_true来读出对应地址的存储内容,并且同时读真实地址rd_ptr自增,代表这个单元已经读取过了,避免重复读取。
  接着是写always部分,与读类似,这里不再详述

//写操作,更新写地址
always @ (posedge clk or negedge rst_n) begin
	if (!rst_n)
		wr_ptr <= 0;//写地址清零
	else if (!full && wr_en)begin								//写使能有效且非满
		wr_ptr <= wr_ptr + 1'd1;
		fifo_buffer[wr_ptr_true] <= data_in;
	end	
end

  注意读写的条件,除了读写有使能之外,还要满足读的时候非空,写的时候非满。
  接下来是FIFO中比较重要的一点,就是读空和写满的判断。在同步FIFO中,由于一直是读指针追赶写指针,因此

  • 如果读写地址完全相同,说明读地址完全追赶上了写地址,说明读空
  • 如果读写地址除了最高位完全相同,说明读写地址的值已经绕了一圈追上了读地址(写地址比读地址大了整个FIFO实际存储空间的大小,循环队列),说明写满
      根据以上关系,就有读写判断assign语句:
//当所有位相等时,读指针追到到了写指针,FIFO被读空
assign	empty = ( wr_ptr == rd_ptr ) ? 1'b1 : 1'b0;
//当最高位不同但是其他位相等时,写指针超过读指针一圈,FIFO被写满
assign	full  = ( (wr_ptr_msb != rd_ptr_msb ) && ( wr_ptr_true == rd_ptr_true ) )? 1'b1 : 1'b0;

  一般的同步FIFO设计到这里就结束了,但是由于上一章中提到,contorl_register中有显示FIFO余量的位域margin,因此需要把FIFO余量在FIFO模块进行输出。
  很容易可以的值FIFO余量margin就是64-写寄存器比读寄存器超前的值。但是,上一章也提到,由于位宽限制,除了64之外的余量都按照其本身表示,而64表示为63.综合以上逻辑,代码如下所示。

assign FIFO_margin_o=(~empty)?((wr_ptr>=rd_ptr)?('d64-(wr_ptr-rd_ptr)):(rd_ptr-wr_ptr)):'b11_1111;

  SCFIFO的整体代码如下
  文件名SCFIFO.v

/****************<slave_FIFO的64深度同步FIFO,指针方式实现>*********************/
/****************<验证见SCFIFO2文件夹>*********************/
`timescale 1ns/100ps
module	SCFIFO
#(
	parameter   DATA_WIDTH = 'd32  ,							//FIFO位宽
    parameter   DATA_DEPTH = 'd64 								//FIFO深度
)
(
	input										clk		,		//系统时钟
	input										rst_n	,       //低电平有效的复位信号
	input	[DATA_WIDTH-1:0]					data_in	,       //写入的数据
	input										rd_en	,       //读使能信号,高电平有效
	input										wr_en	,       //写使能信号,高电平有效
						                                        
	output	reg	[DATA_WIDTH-1:0]				data_out,	    //输出的数据
	output										empty	,	    //空标志,高电平表示当前FIFO已被写满
	output										full,		    //满标志,高电平表示当前FIFO已被读空
    
    output  wire [5:0]                          FIFO_margin_o   //FIFO通道余量64也算作63
);                                                              
 
//reg define
//用二维数组实现RAM
reg [DATA_WIDTH - 1 : 0]			fifo_buffer[DATA_DEPTH - 1 : 0];	
reg [$clog2(DATA_DEPTH) : 0]		wr_ptr;						//写地址指针,位宽多一位	
reg [$clog2(DATA_DEPTH) : 0]		rd_ptr;						//读地址指针,位宽多一位	
 
//wire define
wire [$clog2(DATA_DEPTH) - 1 : 0]	wr_ptr_true;				//真实写地址指针
wire [$clog2(DATA_DEPTH) - 1 : 0]	rd_ptr_true;				//真实读地址指针
wire								wr_ptr_msb;					//写地址指针地址最高位
wire								rd_ptr_msb;					//读地址指针地址最高位
 
assign {wr_ptr_msb,wr_ptr_true} = wr_ptr;						//将最高位与其他位拼接
assign {rd_ptr_msb,rd_ptr_true} = rd_ptr;						//将最高位与其他位拼接

assign FIFO_margin_o=(~empty)?((wr_ptr>=rd_ptr)?('d64-(wr_ptr-rd_ptr)):(rd_ptr-wr_ptr)):'b11_1111;
//读操作,更新读地址
always @ (posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0)begin
		rd_ptr <= 'd0;//读地址清零
		fifo_buffer[0]<=0;//清空首地址数据
		data_out<=0;
	end
	else if (rd_en && !empty)begin								//读使能有效且非空
		data_out <= fifo_buffer[rd_ptr_true];
		rd_ptr <= rd_ptr + 1'd1;
	end
end
//写操作,更新写地址
always @ (posedge clk or negedge rst_n) begin
	if (!rst_n)
		wr_ptr <= 0;//写地址清零
	else if (!full && wr_en)begin								//写使能有效且非满
		wr_ptr <= wr_ptr + 1'd1;
		fifo_buffer[wr_ptr_true] <= data_in;
	end	
end
 
//更新指示信号
//当所有位相等时,读指针追到到了写指针,FIFO被读空
assign	empty = ( wr_ptr == rd_ptr ) ? 1'b1 : 1'b0;
//当最高位不同但是其他位相等时,写指针超过读指针一圈,FIFO被写满
assign	full  = ( (wr_ptr_msb != rd_ptr_msb ) && ( wr_ptr_true == rd_ptr_true ) )? 1'b1 : 1'b0;
 
endmodule

第二节 通道从端slave_FIFO理解

  通道从端接口时序在文档中描述如下

一个通道从端包括图1中的slaveX及FIFOX(X=0,1,2)。其中FIFO深度为64
通道从端从外部接口接收数据,当接收到一个完整的数据包(默认32,由通道X的控制寄存器bit[5:3]决定)后,则向arbiter发出发送请求。
若请求信号得到响应,则开始发送,直至整个数据包全部发送完成后,再根据情况确定是否发出发送数据请求(是否数据多余32,因为这时无法读入)。

如图所示。当chx_valid信号为高时,表示写入数据有效。此周期chx_data应给出要写入的数据。若该时钟周期chx_ready为高,则表示已经将数据写入。若此时钟周期chx_ready信号为低,则表示数据还未写入,需要等待chx_ready为高时才将数据写入。
在这里插入图片描述

  这里输入的大概意思就是,chx_validchx_data是对应关系的,在当前时钟周期,如果chx_data对应的chx_valid是1,则在下个时钟周期被存入FIFO(当然,假设FIFO没满还能存).反之,如果chx_valid是0,那么该数据就不被存入。
  其中chx_ready是发送请求,如果FIFO比较满,则将chx_ready置位低,表示没有准备好接收数据。而在当前时钟周期内,若chx_ready为低,则chx_data同样在下一周期不被写入FIFO。chx_ready的作用是跟外界(即发送数据的模块,这个不再我们设计的范围内)通信,告诉它这个数据并没有接收,让其重新发送。
  确定完输入时序,接下来就是确定如何跟子模块SCFIFO进行连接。首先显而易见的是,fullempty信号并不需要使用,因为这里使用margin来判断FIFO内部的存储情况。
  FIFO复位信号rst_n: 由于除了从端的输入复位之外,还有通道使能和复位有关,因此FIFO的复位信号应该是以上两个信号相与

assign rst_n=rstn_i&slvx_en_i;

  FIFO使能信号wr_en: 如前输入时序所述,需要同时满足chx_readychx_valid才可以正常写入.

assign wr_en=chx_valid_i&chx_ready_o;

  FIFO使能信号rd_en: 相比之下读使能会复杂一些,因为读实质上就是给arbiter发送数据。发送需要遵守发送机制和握手规则。比方说,必须FIFO内至少有一个包才能发送。因为发送以包为单位发送的。此外,还需要arbiter的允许发送信号才可以发送。
  因此可以引入一个计数信号i,以确保发送过程的连续性。同时i还可以用来产生发送的有效信号slavx_val_o.i的相关代码如下

always @(posedge clk_i or negedge rst_n) begin//产生输出长度i计数信号
    if(~rst_n)
        i<=0;
    else if(a2sx_ack_i==1)
        i<=1;
    else if(i>0 && i<pkglen-1)				//^^C语言连续不等式verilog不支持
        i<=i+1;
    else
        i<=0;        
end

  我们期望产生的i的时序如下图所示
在这里插入图片描述

  其中1,2,3分别标志着第1/2/3个数据,0表示最后一个数据或者已经发送完毕当前没有发送任务。其中i的计数量是根据control_register中当前通道的包长度来确定的。如上图所示,我们在i的基础上变换出波形val_i以表征 i 不为0的时刻.此外,根据上级arbiter请求发送信号a2sx_ack_ival_i的关系,我们进行一个波形变换,将其或起来,就得到了rd_en,观察其波形如上图,发现正好满足需要读出数据的时序:给出数据时刻(start,end来表征start上升沿到end下降沿)正好延后读使能rd_en一个时钟周期,符合FIFO的输入输出时序关系。
  确定rd_en后,根据时序关系易知,slavx_val_o就是rd_en延迟一个时钟。
  一点小的改造:由于后续需要输出end信号来表征数据包发送结束,由于在slave_FIFO模块中,我们有变量i来精确追踪输出数据包的时间,因此我们在本模块中产生end信号然后发送给其他模块即可。

assign val_i=(i==0)?0:1;
assign rd_en=val_i | a2sx_ack_i;

第三节 通道从端slave_FIFO代码实现

  综合上2节,代码如下
  文件名:slave_FIFO.v

/*************************<MCDF通道从端>*********************/
`timescale 1ns/100ps
`include "../SCFIFO/SCFIFO.v"
/*************************<端口声明>*********************/
module  slave_FIFO
#(
    parameter   DATA_DEPTH = 'd64 			//FIFO深度
)
(
    input                   clk_i,          //时钟
                            rstn_i,         //复位
                            chx_valid_i,    //外部信号有效信号
                            a2sx_ack_i,     //仲裁器允许读数据包
                            slvx_en_i,      //通道使能(来自寄存器)
    input   wire    [31:0]  chx_data_i,
    input   wire    [2:0]   slvx_pkglen_i,   //本通道数据包长度

    output  wire            chx_ready_o,    //允许接收外部信号(如果FIFO比较满就不接收)
    output  wire    [5:0]   margin_o,       //本通道FIFO余量
    output  wire    [31:0]  slvx_data_o,    //发送给仲裁器的数据
    output  reg             slvx_val_o,     //发送给仲裁器的数据有效
    output  wire            slvx_req_o,      

    output  reg             slvx_end_o     //增加的 
);
/*************************<中间信号>*********************/
wire [5:0] pkglen;
integer i;
wire    wr_en,
        rd_en,
        val_i,//i不为0时该信号为1,用于生成rd_en的中间信号
        rst_n;
assign wr_en=chx_valid_i&chx_ready_o;
assign chx_ready_o=(margin_o>='d32);//这里比较充裕,可以(margin_o<slvx_pkglen_i)
assign rst_n=rstn_i&slvx_en_i;
assign pkglen=2**(slvx_pkglen_i+'d2);//因为slvx_pkglen_i时[2:0]所以+2不会溢出
/*************************<实例化SCFIFO>*********************/
SCFIFO FIFO1(
    .clk(clk_i)		,	
    .rst_n(rst_n)	,    
    .data_in(chx_data_i)	,    
    .rd_en(rd_en)	,    
    .wr_en(wr_en)	,    
                 
    .data_out(slvx_data_o),	 
    .empty(),//保留	 
    .full(), //保留	
    .FIFO_margin_o(margin_o)
);
/*************************<时序电路>*********************/
always @(posedge clk_i or negedge rst_n) begin//产生输出长度i计数信号
    if(~rst_n)
        i<=0;
    else if(a2sx_ack_i==1)
        i<=1;
    else if(i>0 && i<pkglen-1)//^^C语言连续不等式是错误的
        i<=i+1;
    else
        i<=0;        
end
always @(posedge clk_i or negedge rst_n) begin
    if(~rst_n)
        slvx_val_o<=0;
    else
        slvx_val_o<=rd_en;
end

always @(posedge clk_i or negedge rst_n) begin
    if(~rst_n)
        slvx_end_o<=0;
    else if(i==pkglen-1)
        slvx_end_o<=1;
    else
        slvx_end_o<=0;
end
/*************************<组合电路>*********************/
assign val_i=(i==0)?0:1;
assign rd_en=val_i | a2sx_ack_i;
assign slvx_req_o=(margin_o<=DATA_DEPTH-pkglen)?1:0;//如果FIFO使用量大于一个pkglen,则请求发送
endmodule

第四节 通道从端slave_FIFO testbench实现

  文件名:slave_FIFO_tb.v

`timescale 1ns/100ps
`include "slave_FIFO.v"
/*************************<端口声明>*********************/
module  slave_FIFO_tb;
reg             clk_i;       
reg             rstn_i;       
reg             chx_valid_i;  
reg             a2sx_ack_i;  
reg             slvx_en_i;   
reg    [31:0]  chx_data_i;
reg    [2:0]   slvx_pkglen_i;

wire            chx_ready_o;
wire    [5:0]   margin_o;  
wire    [31:0]  slvx_data_o;  
wire            slvx_val_o;  
wire            slvx_req_o;
wire            slvx_end_o;  
/********************<实例化slave_FIFO>*********************/
slave_FIFO  slave1(
                clk_i,       
                rstn_i,       
                chx_valid_i,  
                a2sx_ack_i, 
                slvx_en_i,             
                chx_data_i,
                slvx_pkglen_i,
                
                chx_ready_o,
                margin_o,
                slvx_data_o,  
                slvx_val_o, 
                slvx_req_o,
                slvx_end_o  
);
initial begin
    clk_i<=0;//
    rstn_i<=0;//
    chx_valid_i<=1;
    a2sx_ack_i<=0;
    slvx_en_i<=1;//
    chx_data_i<=$random;
    slvx_pkglen_i<=2'b00;//
    $dumpfile("slave_FIFO.vcd");
    $dumpvars;
#25 rstn_i<=1;//
repeat(2)begin
    @(posedge clk_i)begin
        chx_valid_i<=1;
        chx_data_i<=$random;            
    end
end
    @(posedge clk_i)begin
        chx_valid_i<=0;
        chx_data_i<=$random;    
    end
repeat(5)begin
    @(posedge clk_i)begin
        chx_valid_i<=1;
        chx_data_i<=$random;            
    end
end
@(posedge clk_i)
a2sx_ack_i<=1;
@(posedge clk_i)
a2sx_ack_i<=0;chx_valid_i<=0;
#100
@(posedge clk_i)
a2sx_ack_i<=1;
@(posedge clk_i)
a2sx_ack_i<=0;
#200
repeat(40)begin
    @(posedge clk_i)begin
        chx_valid_i<=1;
        chx_data_i<=$random;            
    end
end
    #2000 $finish;
end
always #10 clk_i<=~clk_i;
endmodule

  用gtkwave观察波形,
  存入FIFO的数据如下图所示
在这里插入图片描述  
  读出数据,以及中间信号时序如下图,可以发现数据被正确读出了
在这里插入图片描述  
  连续读取两次波形如下图所示
在这里插入图片描述
  以上便是输入从端slave_FIFO的设计和测试


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/83031.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【随机分形搜索算法】一种新的全局数值优化的适应度-距离平衡随机分形搜索算法FDB-SFS附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

模型精度再被提升,统一跨任务小样本学习算法 UPT 给出解法!

近日&#xff0c;阿里云机器学习平台PAI与华东师范大学高明教授团队、达摩院机器智能技术NLP团队合作在自然语言处理顶级会议EMNLP2022上发表统一多NLP任务的预训练增强小样本学习算法UPT&#xff08;Unified Prompt Tuning&#xff09;。这是一种面向多种NLP任务的小样本学习算…

【HMS Core】运动健康服务上传平台的健康数据,能否获取到上传设备的SN码或者唯一设备码信息

问题描述 上传平台的健康数据&#xff0c;能否获取到上传设备的SN码或者唯一设备码信息 解决方案 DeviceInfo中包含华为设备唯一标识&#xff0c;您可以通过DeviceInfo进行查看。 DeviceInfo Android API&#xff1a;https://developer.huawei.com/consumer/cn/doc/developm…

价值年薪50W的软件测试进阶学习路线,终于让我从阿里P8手里抠出来了

作为一个男人我感觉必须得做点什么来证明一下自己&#xff0c;现在我又回来了&#xff0c;准备把自己的节操准备补一下。另外给各位未来的自动化测试工程师和测试开发工程师说一句&#xff0c;别的我不清楚&#xff0c;学习编程请从一而终 咱们学习编程就挺难的&#xff0c;有…

Matplotlib学习笔记(第二章 2.14 图像教程)

2.1.4 图像教程 使用Matplotlib绘制图像的简短教程。 启动命令 首先&#xff0c;让我们开始IPython。它是对标准Python提示符的最优秀的增强&#xff0c;它与Matplotlib结合得特别好。直接在shell上启动lPython&#xff0c;或者使用Jupyter笔记本(其中IPython作为运行的内核…

为什么 Android 要采用 Binder 作为 IPC 机制?

前言 Android 系统为了安全、稳定性、内存管理等原因&#xff0c;Android 应用和系统服务都是运行在独立的进程中的&#xff0c;但系统服务与应用进程之间&#xff0c;应用进程A与应用进程B之间需要通信和数据共享的。因此&#xff0c;Android 系统需要提供一套能够高效、安全…

js 踩了正则表达式的大坑!lastIndex属性

参考文章 踩坑情景 今天一来&#xff0c;被测试测出了一个问题&#xff0c;在使用vantUI的移动端项目中&#xff0c;我虽然对用户输入的值做了去除首尾空格的操作&#xff0c;但却忘记对用户输入的空值进行错误提示&#xff0c;fine&#xff0c;我选择给表单添加rules规则&am…

[附源码]JAVA毕业设计远程教学系统录屏(系统+LW)

[附源码]JAVA毕业设计远程教学系统录屏&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术…

40个高质量SSM毕设项目分享【源码+论文】

文章目录前言 题目1 : 基于SSM的房屋出租出售系统 <br /> 题目2 : 基于SSM的房屋租赁系统 <br /> 题目3 : 基于SSM的个人健康信息管理系统 <br /> 题目4 : 基于SSM的共享充电宝管理系统 <br /> 题目5 : 基于SSM的即动运动网站 <br />前言 &…

【C语言数据结构(基础篇)】第二站:顺序表

目录 一、线性表 二、顺序表的实现&#xff08;概念以及静态顺序表&#xff09; 1.创建三个工程文件 2.顺序表的概念 3.顺序表的定义 4.初始化顺序表 5.静态顺序表的尾插 三、顺序表的实现&#xff08;升级为动态顺序表&#xff09; 1.动态顺序表的定义 2.动态顺序表的…

艾美捷NCTC-135培养基化学性质和基本配方

艾美捷NCTC-135培养基背景&#xff1a; NCTC培养基&#xff0c;由马里兰州贝塞斯达国家癌症研究所&#xff08;NCI&#xff09;生物实验室组织培养科开发&#xff0c;用于建立和维持L929小鼠细胞株。 艾美捷NCTC-135培养基化学性质&#xff1a; 外观&#xff1a;白色至浅粉色…

[附源码]Python计算机毕业设计Django超市商品管理

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Android -- 每日一问:谈谈MVC、MVP和MVVM模式,你有在自己的项目中使用过吗?

经典回答 MVC 模式 全名是Model–View–Controller&#xff0c;是模型(model)&#xff0d;视图(view)&#xff0d;控制器(controller)的缩写&#xff0c;一种软件设计典范&#xff0c;用一种业务逻辑、数据、界面显示分离的方法组织代码&#xff0c;在改进和个性化定制界面及用…

[附源码]Python计算机毕业设计SSM基于的高速收费系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

防火墙双机热备配置实验

目录 一、实验拓扑 二、配置云 三、配置防火墙 四、分配FW的接口地址与安全区域 五、按图示进行配置 六、双机热备的配置 七、配置NAT 八、模拟双机热备的切换 一、实验拓扑 看上去挺复杂的其实这个实验还是比较简单的&#xff0c;Client1配置为IP 10.3.0.10 网关10.3.…

python教程十二 字典

字典 字典是另一种可变容器模型&#xff0c;且可存储任意类型对象。 字典的每个键值 key>value 对用冒号 : 分割&#xff0c;每个对之间用逗号(,)分割&#xff0c;整个字典包括在花括号 {} 中 ,格式如下所示&#xff1a; d {key1 : value1, key2 : value2, key3 : value3…

学会模态计算,你就掌握了结构振动冲击计算的核心

模态计算对于认识结构振动特性至关重要&#xff0c;通过模态计算可以得到模态的固有频率&#xff0c;振型&#xff0c;参与系数和有效质量等参数&#xff0c;模态计算的这些参数我们应该很熟悉&#xff0c;但是如果正确合理的使用这些结果指导工程计算&#xff0c;是我们今天讨…

[附源码]Python计算机毕业设计滁州市围棋协会Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

12月12日: 学习跟着猫叔写代码

视频地址&#xff1a;fastadmin系列教程:小白学习之路 学前准备 安装过程 数据库分析 关联查询搜索 数据校验 视图渲染 api登录注册 token验证 table表格_哔哩哔哩_bilibili 前两节是安装fastadmin操作&#xff08;可参考我自己的文章&#xff09; 11月30日&#xff1a;linux服…

当要测试的对象依赖另一个无法控制的对象(系统相关、第三方服务等),这个时候我们应该如何测试?

一.问题描述 判断文件是否有效的需求变更了&#xff1a;有效的文件扩展名存储在文件系统中&#xff0c;要测试的FileVerify类就依赖FileExtensionManager类&#xff0c;在这种场景下如何测试FileVerify类的逻辑呢? 1 public class FileVerify2 { 3 …