Is pass-by-value/reference equivalent to making a deep/shallow copy, respectively?

No. Those two things are completely unrelated.

Shallow copy/deep copy is talking about object copying; whereas pass-by-value/pass-by-reference is talking about the passing of variables.

In many modern languages, like Python (which you mentioned that you're most familiar with) and Java, "objects" are not values in the language, so "objects" cannot be assigned or passed. Rather, objects are always manipulated through pointers to objects (references), which are values and can be assigned or passed.

Python and Java are pass-by-value only. When you pass a reference, it copies the pointer and you end up with two pointers to the same object. No object copying happens. In these languages, object copying is not done through assigning or passing, but rather is done by calling special methods like .clone() or by passing an object to a constructor to construct a new object. (There is in fact no general way to copy an object in Java.)

There are some languages, like C++, where objects can be values (of course, you can also have pointers to objects, which work similarly to references in other languages). C also has both pass-by-value and pass-by-reference. If you pass an object by reference, no copying happens. If you assign or pass an object by value, the object is copied. But by default this is a shallow copy.

The distinction between shallow copy and deep copy is how they deal with members of the object which are pointers to another object. Members which are not pointers are simply copied; there is no concept of "shallow" or "deep". "Shallow" or "deep" only talks about members which are pointers -- whether to copy the object pointed to or not. The default assignment operator and copy constructor in C++ simply copies each member. For members that are pointers, that means the pointer is copied and thus you have two pointers to the same object. That is a shallow copy.

You might want a "deep" copy in cases where the member that is a pointer to another object is really pointing to a "sub-object" that is really "a part of" your object (whether a pointer to another object means a sub-object or not depends on the design of your objects), so you don't want multiple of your objects pointing to the same sub-object, and that's why you want to copy the sub-object when copying the main object. To implement this in C++, you would need to implement a custom assignment operator and custom copy constructor to copy the "sub-objects" in the process of copying. In other languages, you would similarly need to customize whatever copying method is used.